【发布时间】:2016-04-05 15:38:01
【问题描述】:
我不确定 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)。如有任何建议,我将不胜感激...
谢谢, --拉齐
编辑:
再次强调一下:在过去,非绑定代码确实表现出变化,但最多在 10-15% 左右,平均而言,它非常接近于 cpu 绑定代码(在1-2%)。只是从上周末开始,我们才开始看到这种变化,据我们所知,环境没有任何变化。但是(显然)一定发生了一些变化,我想知道它可能是什么。
EDIT2:
我通过 perf 运行代码(重复 10 次),这就是我得到的。
使用 cpu 绑定:
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% )
请注意,代码是确定性的,即它始终采用相同的执行路径。但是有可能一个线程正忙于等待轮到它与全局确定性状态同步。但是为什么会在周期/指令/等方面造成如此巨大的差异......
还请注意,我已尝试将线程以随机顺序固定到内核,以检验按照创建顺序将线程固定到内核会产生影响的假设。但这并没有什么区别,它仍然很快。
【问题讨论】:
-
虽然时间差异很大,但我怀疑数据局部性至关重要,而跨内核的线程迁移是造成这种情况的原因。我不禁想知道您的算法是否最大限度地利用了 CPU 中的 L1 和 L2 缓存。您能否就该算法的作用提供一些见解?
-
另外,你确定你的代码是可重入的吗?任何互斥体,任何需要更新的共享结构?
-
它是一个混合整数规划求解器。是的,缓存位置确实很重要(不幸的是,我们只得到了大约 90% 的缓存命中率,而且看起来不可能改进)。直到上周末,非绑定代码和 CPU 绑定代码之间的差异为 1-2%,而我们在非绑定代码中观察到的最大变化约为 10-15%。毕竟机器没有加载,内核没有理由频繁迁移线程。是的,代码是可重入的,而且就 helgrind 来说它是正确的。
-
您可能需要分析您的算法。它会与外界互动吗?任何文件或套接字 i/o?
-
编辑了帖子,因为很难在评论中添加表格...
标签: linux multithreading performance binding cpu