You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

大量连续nop指令基准测试:周期突增原因及后续疑问

关于指令缓存缺失测试中2^23 NOP处周期突增的问题解答

测试背景回顾

在Ubuntu 22.04 + 11代Intel i5-11400H环境下,通过生成以NOP指令为主、相互调用的x86-64汇编函数,使用Google Benchmark对含210到229数量NOP的函数做基准测试,计算单NOP周期数时发现:NOP数量接近2^23时周期数突然飙升。后续用perf分析排除了TLB缺失,icache_data.stalls曲线与基准测试周期曲线完全吻合,但L2缓存缺失数据存在异常。

疑问解答

1. 按函数事件采样数的测量方法是否合理?

这种方法在指令流主导的性能测试中具备参考性,但存在明显局限性,需结合场景判断:

  • 合理场景:当测试函数为纯NOP+简单调用链时,icache_data.stalls这类指令相关事件的采样几乎完全集中在指令加载阶段,若perf采样频率足够高(避免错过缓存边界的突变点),且Google Benchmark的迭代已进入稳定阶段(排除热身干扰),按函数统计事件数能大致反映该函数内的指令缓存行为。
  • 局限性:
    • 采样偏差:纯NOP指令执行无数据依赖,CPU乱序执行、分支预测会让采样点集中在调用/返回指令或缓存边界处,若采样周期过大,会掩盖局部的性能突变。
    • 统计精度:若采用perf report按函数统计事件占比,不如直接用perf stat -e <事件名> -r <重复次数> ./bench统计全局事件数再除以总NOP数的精度高——后者能避免采样点分布不均带来的误差。
    • 边界干扰:当函数大小跨越缓存行/页边界时,采样点可能过度集中在边界指令,导致统计结果偏离真实的平均周期。

2. 若慢因是缓存缺失,为何预取逻辑未处理顺序加载?

11代Intel Tiger Lake(i5-11400H)的指令预取器对连续指令流的预取能力有限,结合测试场景,主要原因如下:

  • 缓存层级容量限制:i5-11400H的单核心L1I缓存为32KB,单核心L2缓存为1.25MB,而2^23字节(8MB)远超过这两级缓存的容量,指令需从共享L3缓存甚至内存加载。L3的访问延迟(约30-40周期)远高于L2(约10周期),且L3预取带宽有限,预取速度跟不上CPU的指令执行带宽(每周期可执行多条NOP),必然引发stall。
  • 预取器跟踪范围限制:Intel的L2指令预取器有固定的跟踪窗口,对于超长的单次顺序指令流(测试中是调用函数后一次性执行所有NOP再返回),预取器无法提前将L3中的所有指令行预取到L2——当CPU执行完L2内的指令后,后续指令需要等待L3的加载,导致icache stall。
  • 函数调用打断预取跟踪:每次函数调用/返回都会改变指令指针,预取器需要重新建立连续指令流的跟踪逻辑。对于超长NOP序列,调用后的指令流虽连续,但预取器重新初始化跟踪的过程会延迟L3预取的触发,进一步加剧指令加载的等待时间。
  • 事件统计误解:你提到的“L2缺失数据异常”,大概率是统计了数据缓存L2缺失(如l2_cache_misses),而指令缓存的L2缺失需要查看专门的事件(如Tiger Lake的icache_misses.l2_miss)。若混淆了指令/数据缓存的事件统计,自然会出现数据与icache_data.stalls不匹配的情况。

内容的提问来源于stack exchange,提问作者Box Box Box Box

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 08:27:26