通过IPC指标诊断性能问题

注:本文内容引用自张洋老师的知乎文章 https://zhuanlan.zhihu.com/p/...,他是一位存储研发专家。

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(每周期指令数)。

image.png

从这个结果可见,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节点访问导致内存访问延迟更高等。

image.png

节点间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的差异对比。

差分火焰图示例:在该例中,可以发现pool_event_handler消耗的CPU明显增加,正是因为该函数执行了无效代码,拉高了IPC。接下来我们可以结合代码逻辑,继续分析该函数CPU消耗增加的原因。

image.png

两套不同环境下的IPC对比

例如,一套环境是Intel服务器,另一套是其他服务器架构。目前来看,Intel服务器的性能相对较好。例如,在Intel服务器上,当IOPS=200万时,IPC=0.8,而在其他服务器上,IOPS=130万,IPC=0.75。如果在Intel服务器上降低IO负载,使IOPS也为130万,此时IPC=1.2。这表明Intel服务器上CPU和内存等部件运转得更加高效。因此,两套环境产生的性能差异,同样可以根据IPC偏低的线索深入分析。

以海光CPU为例,下图显示zStorage在海光CPU上空闲状态下测得的IPC为1.8,可见这个数据与Intel上的表现相当,意味着每个时钟周期可以平均处理1.8条指令。 (前文已介绍,zStorage运行在轮询模式,即使没有IO负载也会100%占用CPU,不断轮询各个注册的poller。这些poller在无IO负载时通常返回IDLE状态,在有IO负载时返回BUSY状态。)

如图所示,海光平台不仅可以测量IPC,还可以测量前端停顿周期(stalled-cycles-frontend)和后端停顿周期(stalled-cycles-backend)。

stalled-cycles-frontend:前端停顿周期比例(19.35%),表示由于前端无法提供指令导致的停顿。较高比例可能是指令获取的瓶颈。
stalled-cycles-backend:后端停顿周期比例(24.08%),表示后端等待前端提供指令的停顿时间。高比例可能是执行单元等待数据的表现,通常与内存瓶颈相关。

一旦施加一定IO负载,程序的内存访问量增加,导致前后端停顿增加,从而使IPC降低。可以根据stalled-cycles-frontend和stalled-cycles-backend指标进一步确认程序的瓶颈……

image.png

总结

本文描述了通过IPC指标可以快速定位一些性能问题,从而指导下一步性能调优的方向。但这并不意味着只能通过IPC来揭示文中所述的一些问题,实际上,通过perf生成CPU占用的火焰图也可以达到类似的效果。

火焰图示例:

image.png

END

作者:“云和恩墨 zStorage 分布式存储团队” 张洋
原文:企业存储技术

推荐阅读

欢迎关注企业存储技术极术专栏,欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
推荐阅读
关注数
5612
内容数
260
关注存储、服务器、图形工作站、AI硬件等方面技术。WeChat:490834312
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息