为什么我的基准测试随机出现 运行 3 倍的速度,为什么 运行 在 perf 中使用它会使这种情况更频繁地发生?

Why does my benchmark randomly appear to run 3x as fast, and why does running it inside perf make this happen much more often?

我写了一个基准来测试一些特定的功能。 运行 基准测试通常会给出一致的结果,但在每个基准测试用例中,大约十分之一的结果似乎 运行 快了 3 倍。

我想知道是否有某种 b运行ch 预测或缓存位置问题影响了这一点,所以我 运行 它在 perf 中,像这样:

sudo perf stat -B -e cache-references,cache-misses,task-clock,context-switches,cpu-migrations,page-faults,cycles,instructions,branches,branch-misses ./my_benchmark

现在结果反转:大约十分之九的速度运行s 更快,在这种情况下perf stat 输出如下所示:

 Performance counter stats for './my_benchmark':

           336,011      cache-references          #   75.756 M/sec                    (41.40%)
            74,722      cache-misses              #   22.238 % of all cache refs    
          4.435442      task-clock (msec)         #    0.964 CPUs utilized          
                 0      context-switches          #    0.000 K/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
               572      page-faults               #    0.129 M/sec                  
        13,745,945      cycles                    #    3.099 GHz                    
        16,521,518      instructions              #    1.20  insn per cycle         
         4,453,340      branches                  # 1004.035 M/sec                  
            91,336      branch-misses             #    2.05% of all branches          (58.60%)

       0.004603313 seconds time elapsed

在大约十分之一的试验中,它 运行 慢了 3 倍,显示的结果如下:

 Performance counter stats for './my_benchmark':

           348,441      cache-references          #   22.569 M/sec                    (74.14%)
           112,153      cache-misses              #   32.187 % of all cache refs      (74.14%)
         15.439061      task-clock (msec)         #    0.965 CPUs utilized          
                 0      context-switches          #    0.000 K/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
               572      page-faults               #    0.037 M/sec                  
        13,717,144      cycles                    #    0.888 GHz                      (62.52%)
        16,951,632      instructions              #    1.24  insn per cycle           (88.40%)
         4,463,213      branches                  #  289.086 M/sec                  
            70,185      branch-misses             #    1.57% of all branches          (89.20%)

       0.015999175 seconds time elapsed

我注意到任务似乎总是在大致相同的 周期数 内完成,但频率不同——在 "fast" 情况下它显示大约 3GHz,而在慢速情况下它显示大约 900 MHz。不过,我并不清楚这个统计数据意味着什么,所以我不知道这是否只是相似循环次数和更长 运行 时间的重言式结果,或者它是否意味着处理器的时钟实际上是 运行以不同的速度宁。

我确实注意到,在这两种情况下,它都显示 "context switches: 0" 和 "cpu migrations: 0,",所以看起来放缓并不是因为基准测试被抢占了。

这是怎么回事,我能否以始终获得更快性能的方式编写(或启动?)我的程序?

经常 CPU 频率根据负载变化...我会在 运行 之前强制锁定频率

你在OS什么?