什么会导致多线程代码运行时的巨大变化

时间:2016-04-05 15:38:02

标签: linux multithreading performance binding cpu

我不确定stackoverflow是否是最好的论坛,但在这里......

我们正在对我们的软件进行基准测试。突然间,我们看到了巨大的性能下降。为了测试发生了什么,我们多次在同一输入上运行软件。结果令人吃惊(巨大的性能变化):

Solution time = 9.69 sec.
Solution time = 7.55 sec.
Solution time = 4.78 sec.
Solution time = 5.12 sec.
Solution time = 6.94 sec.
Solution time = 2.15 sec.
Solution time = 5.48 sec.

我们的软件是多线程的,在12核机器的每个核心(超线程被禁用)上只启动一个线程。机器上没有其他任何东西在运行。在周末之前,我们从来没有在运行时发生这样的变化。

一时兴起,我们在启用cpu绑定的情况下重复测试(即将12个线程中的每一个都固定到不同的核心):

Solution time = 0.95 sec.
Solution time = 0.95 sec.
Solution time = 0.95 sec.
Solution time = 0.95 sec.
Solution time = 0.94 sec.
Solution time = 0.95 sec.
Solution time = 0.95 sec.

此时我不知道是什么原因引起的。据我们所知,机器的配置没有任何改变(RHEL 6.6)。我对任何建议表示感谢......

谢谢, --Laci

修改

再次强调:在过去,非绑定代码确实表现出变异,但最多只有10-15%的数量级,并且平均而言它非常接近cpu绑定代码(在1-2%)。从上周末开始,我们开始看到这种变化,据我们所知,环境没有任何变化。但(显然)某些事情必定会发生变化,我想知道它本来可能是什么。

EDIT2

我通过perf运行代码(重复10次),这就是我得到的。

使用cpu-binding:

   15713.138442  task-clock-msecs         #      9.341 CPUs    ( +-   0.037% )
           6958  context-switches         #      0.000 M/sec   ( +-   0.357% )
             11  CPU-migrations           #      0.000 M/sec   ( +-   1.786% )
          49147  page-faults              #      0.003 M/sec   ( +-   0.514% )
    45890046261  cycles                   #   2920.489 M/sec   ( +-   0.030% )
    51929307378  instructions             #      1.132 IPC     ( +-   0.021% )
    11050565282  branches                 #    703.269 M/sec   ( +-   0.032% )
      446256370  branch-misses            #      4.038 %       ( +-   0.003% )
      421789915  cache-references         #     26.843 M/sec   ( +-   0.048% )
       18989944  cache-misses             #      1.209 M/sec   ( +-   0.305% )

    1.682190890  seconds time elapsed   ( +-   0.131% )

没有cpu绑定:

   36219.945761  task-clock-msecs         #      5.677 CPUs    ( +-   3.978% )
           8742  context-switches         #      0.000 M/sec   ( +-   1.677% )
             34  CPU-migrations           #      0.000 M/sec   ( +-   5.243% )
          48799  page-faults              #      0.001 M/sec   ( +-   0.839% )
   106384797638  cycles                   #   2937.188 M/sec   ( +-   3.989% )
    93465235493  instructions             #      0.879 IPC     ( +-   3.085% )
    23685574664  branches                 #    653.937 M/sec   ( +-   3.672% )
      477076300  branch-misses            #      2.014 %       ( +-   0.563% )
      414008416  cache-references         #     11.430 M/sec   ( +-   0.189% )
       17910783  cache-misses             #      0.495 M/sec   ( +-   1.468% )

    6.380128466  seconds time elapsed   ( +-   5.171% )

请注意,代码是确定性的,即它始终采用相同的执行路径。但是线程可能正在忙 - 等待轮到与全局确定性状态同步。但是为什么会在周期/指令/等方面造成如此巨大的差异......

另请注意,我已尝试以随机顺序将线程固定到核心,以测试这样的假设,即按照创建顺序将它们转移到核心会产生影响。但这没有任何区别,它仍然很快。

1 个答案:

答案 0 :(得分:2)

问题得到解决。根据ekarak的建议,我深入剖析了剖析图,发现当我们的线程相互作用并等待彼此时浪费时间。在预感中,我重新启动了机器,然后一切都恢复正常。

现在,我们在群集中有40台计算机,并且都表现出这种行为。这意味着存在外部影响或机器的正常运行时间起作用。我搜索了“linux uptime 209”,结果发现在内核中这些机器正在运行,sched_clock()中有一个溢出错误,在208.5天后被触发。

所以...我们遇到了与机器上的线程交互相关的问题,这些问题已经持续了209天,sched_clock()中有一个错误,它在208.5天后出现。这对我来说太巧合了,所以我总结说这是我们的问题。