ARM Cortex A78AE中stall_slot_backend事件相关技术咨询
我正在诊断一个小程序的低指令周期问题,执行perf stat -e cycles,stalled-cycles-backend ./myprogram后,发现约90%的后端周期处于空闲状态,统计数据如下:
Performance counter stats for './myprogram': 5207951548 cycles:u 4704755172 stalled-cycles-backend:u # 90.34% backend cycles idle 3.485708464 seconds time elapsed
我知道stalled-cycles-backend硬件计数器会在因内存加载结果、浮点单元不可用等资源限制导致取指无法分派、流水线出现气泡时递增,想进一步排查后端停滞的具体原因。
通过perf list查看其他事件时,发现这些内核PMU事件:
--snip-- stall_slot [Kernel PMU event] stall_slot_backend [Kernel PMU event] stall_slot_frontend [Kernel PMU event] --snip--
执行perf stat -e cycles,stall_slot_backend .build/release/Run得到结果:
Performance counter stats for './myprogram': 5207682200 cycles:u 28628535485 stall_slot_backend:u
该事件计数远超时钟周期数,我对此感到困惑。根据ARM Cortex A78AE技术参考手册,stall_slot_backend的描述为:
No operation sent for execution on a slot due to the backend
描述不够清晰,且我未在手册中找到slot的定义,因此有以下疑问:
- 此场景下的slot具体指什么?
- 为何该事件计数超过时钟周期数?计数器是否可能在每个周期递增多次?结果是否存在误差或误导性?
stall_slot_backend与stalled-cycles-backend硬件事件/事件组的区别是什么?
问题解答
1. 什么是slot?
在ARM Cortex-A78AE这类超标量CPU中,slot指的是每个时钟周期内处理器可以派发指令的执行单元位置。A78AE是乱序执行架构,每个周期最多可以向多个执行单元(比如整数、浮点、加载存储单元等)派发指令,每个可用于派发的位置就是一个slot。比如A78AE每个周期最多支持派发4条指令,对应4个slot。
2. 为什么计数远超时钟周期?
没错,这个计数器每个周期可以递增多次,这就是计数远超cycles的原因。
比如每个周期有4个slot,如果某个周期里因为后端资源限制,这4个slot都没能派发任何指令,那stall_slot_backend就会加4;如果有2个slot被阻塞,就加2。你的程序里90%的后端周期空闲,意味着大部分周期里多个slot都处于停滞状态,总计数自然会远高于总周期数。这个结果是准确的,没有误差或误导性,它反映的是后端停滞的总slot数量,而非停滞的周期数。
3. 两个事件的区别
stalled-cycles-backend:统计的是至少有一个后端slot停滞的时钟周期数。只要某个周期里存在后端导致的停滞,这个计数器就加1,不管该周期里有几个slot停滞。你之前的结果显示90.34%的周期都存在后端停滞,说明程序大部分时间都在等后端资源。stall_slot_backend:统计的是所有因后端原因停滞的slot的总数量。它是按slot计数,每个停滞的slot都会让计数器加1,所以数值是周期数乘以每个周期停滞的slot数的总和,这也是它比cycles大的核心原因。
简单说,前者看的是“有多少个周期后端没干活”,后者看的是“总共有多少个可执行的位置没用到”,后者能更精准地量化后端资源浪费的程度。
内容的提问来源于stack exchange,提问作者loonatick

