注:本文内容引用自张洋老师的知乎文章 https://zhuanlan.zhihu.com/p/3613097921
,他
是一位存储研发专家。
IPC是什么
IPC(Instructions Per Cycle)是指每个周期的指令执行数,用于衡量处理器的执行效率。IPC越高,表明处理器在相同频率下可以执行更多指令。
在现代高性能处理器中,每个时钟周期可以发射4~6条指令,因此在理想情况下,IPC可以达到4~6以上。然而在实际情况中难以达到,主要原因包括数据依赖、缓存未命中(Cache Miss)、分支预测错误等。
因此,较低的IPC意味着CPU执行效率低,CPU有大量时间处于停滞等待状态,无法有效利用硬件的峰值性能。
使用perf工具测量IPC
perf
是Linux系统中一个强大的性能分析工具,广泛用于分析和调试应用程序、内核、硬件等性能问题。它可以监测多种性能事件,例如指令周期、缓存命中率、分支预测准确率、IPC(每周期指令数)等。
perf
提供了详细的报告,帮助用户识别性能瓶颈,从而优化系统或应用。
perf工具测量IPC示例:perf stat -C 32,4,36,8,40,12,44,16,48,20,52,24,56,28,60,2,34,6,38 sleep 10
该命令使用
perf stat
来测量指定CPU核心(-C 后的核心列表)上的性能指标,运行
sleep 10
来采集10秒的数据,包括指令数、周期数和IPC(每周期指令数)。
从这个结果可见,
perf stat
命令默认包含了测量指令数(instructions)和周期数(cycles),使用指令数除以周期数便得到了IPC。当前测量的这些CPU的IPC均值为1.76(1.76 insn per cycle)。1.76这个数据是在zStorage没有任何IO负载、空转时测量的。可见,要在存储系统软件上达到理想的IPC 4以上,似乎非常困难。
zStorage基于SPDK开发,使用SPDK的轮询模式,所以即使在没有IO负载时,CPU的使用率也为100%。(后续的实验均基于轮询模式测试)
从IPC指标可以体现哪些性能问题
与基线做对比,初步诊断性能问题
在性能正常的情况下,测量IPC指标。例如,下图为4k随机写测试时,IPC指标为0.81。如果某个分支的IPC更低,比如只有0.7,那么性能问题的排查方向应为内存访问效率、分支预测失败等。可能的原因是:IO路径上内存工作集增加,导致更多的cache miss;或者内存条数量不够,导致内存带宽不足;亦或是跨NUMA节点访问导致内存访问延迟更高等。
节点间IPC差异过大问题
在zStorage分布式存储系统中,各个节点以及各个CPU核心上的IO负载理论上是均衡的。如果通过
perf
工具测量发现IPC在节点间或者CPU核心间差异很大,例如一个节点为0.8,另一个节点却为0.7,这意味着IPC为0.7的节点负载更大,需要分析负载不均衡问题。同样地,通过测量不同CPU核心间的IPC,如果差距过大,也可以反映CPU核心间的负载不均衡。
如果节点间、CPU核心间的工作不均衡,则会出现“忙的忙死,闲的闲死”的情况,无法充分利用资源性能。忙的组件将成为明显的性能瓶颈,从而影响整体性能表现。
IPC增加,但是IOPS性能数据下降
是否有可能出现“IPC增加,但是IOPS性能数据下降”的情况呢?例如,基准IPC为0.8,IOPS为200万,而异常情况下IPC为0.9,IOPS为180万。这表明CPU虽然在卖力地工作,但却做了许多无用功。
这种情况可以通过对比两种IPC情况下的
perf
火焰图,再生成差分火焰图。
火焰图(Flame Graph)是一种可视化工具,用于展示程序或系统的CPU性能分析结果。它将函数调用栈结构绘制成层叠的“火焰”形状,通过条形的宽度表示CPU在每个函数上的占用时间,宽度越大,函数越消耗资源。火焰图常用于识别性能瓶颈和高CPU占用的代码路径。
差分火焰图(Differential Flame Graph)通过对比两组火焰图的数据差异,将性能变化可视化。通常,一组火焰图为基准状态,另一组为调整后的状态。对比结果会用不同颜色表示变化——如红色表示性能退化,绿色表示性能提升。差分火焰图在性能调优和资源利用的对比分析中很有帮助,尤其是测量两种IPC的差异对比。