内存性能引发的程序性能恶化案例

在一台机器上测试spec。发现性能很差。使用top去看,发现cpu可以占满,但即便能占用大量cpu资源吞吐量却上不去。使用perf stat去看。

# perf stat -a -p 946806
PID/TID switch overriding SYSTEM
^C
 Performance counter stats for process id '946806':

      6,025,883.23 msec task-clock                #  140.887 CPUs utilized
           312,303      context-switches          #   51.827 /sec
            30,953      cpu-migrations            #    5.137 /sec
             5,271      page-faults               #    0.875 /sec
18,419,584,593,620      cycles                    #    3.057 GHz
 1,706,212,757,162      stalled-cycles-frontend   #    9.26% frontend cycles idle
 5,115,942,543,739      stalled-cycles-backend    #   27.77% backend cycles idle
   379,510,007,890      instructions              #    0.02  insn per cycle
                                                  #   13.48  stalled cycles per insn
    77,529,286,532      branches                  #   12.866 M/sec
     2,348,792,126      branch-misses             #    3.03% of all branches

      42.771131433 seconds time elapsed

IPC低到只有0.02. stalled-cycles-backedn较高,这个值意味着指令在pipline中的执行阶段等待,cache miss(未显示)较低,cache-reference,context-switches很低,branch-miss也很低。这个给出的cpu运行画像就是一个程序在龟速执行,但是cpu主频是很高的,也就是很多时候cpu流水线在空等。但是感觉27.8的stalled-cycles-backed似乎解释不了这么大差距,再加上9%的stalled-cycles-frontend,也就是接近40%的时间是在空耗。但是IPC比正常(0.5)左右还是低了20多倍。“13.48 stalled cycles per insn” 这一行似乎可以说明问题,平均下来每条指令要经过13cycle的等待。

测试一下内存带宽,使用lmbench,同时看perf stat的情况:

perf stat -p 1624296 -- sleep 10

 Performance counter stats for process id '1624296':

         10,001.09 msec task-clock                #    1.000 CPUs utilized
                11      context-switches          #    1.100 /sec
                 4      cpu-migrations            #    0.400 /sec
                 3      page-faults               #    0.300 /sec
    29,999,862,632      cycles                    #    3.000 GHz
       210,826,110      stalled-cycles-frontend   #    0.70% frontend cycles idle
    29,654,123,819      stalled-cycles-backend    #   98.85% backend cycles idle
       132,381,904      instructions              #    0.00  insn per cycle
                                                  #  224.00  stalled cycles per insn
        20,053,547      branches                  #    2.005 M/sec
         1,397,823      branch-misses             #    6.97% of all branches

      10.002876336 seconds time elapsed

这就很能说明问题了,IPC低到看不到了,stalled-cycles-backed几乎百分百了,看来读写内存是一个重要的性能瓶颈。虽然在spec中测试stalled-cycles-backend并不是太高,那是被其他不读写内存的指令稀释了,专门测试内存性能才能更明显的看出问题。平均每个指令都要有200多的cycle等待,这个就很能说明问题,指令在执行的时候大部分时间都在等待内存读写的完成。

posted @ 2024-04-12 13:44  半山随笔  阅读(36)  评论(0编辑  收藏  举报