我想在集群的一个节点上运行STREAM 基准测试的MPI 版本,以测量不同 MPI 进程数量的可持续带宽。每个节点由两个英特尔® 至强® 处理器 E5-2680 v3(12 核)组成。
在下文中,我将使用openmpi v. 1.8.2 和选项map-by core
. 源代码是使用包装器编译的
icc (ICC) 15.0.0 20140723
使用编译器选项
-O3 -xHost.
每个核心一直使用长度为 2*10^6 的双精度数组,测试重复 50 次:
01: Triad: 22017.3438
02: Triad: 29757.8394
03: Triad: 30224.1759
04: Triad: 30080.7369
05: Triad: 30209.6233
06: Triad: 30028.2044
07: Triad: 35064.7215
09: Triad: 44961.7710
10: Triad: 49721.1975
11: Triad: 54814.0579
12: Triad: 58962.7279
13: Triad: 64405.3634
14: Triad: 69330.3864
15: Triad: 74137.0623
16: Triad: 78838.8075
17: Triad: 84006.1067
18: Triad: 89012.6674
19: Triad: 94105.8690
20: Triad: 98744.3634
21: Triad: 103948.1538
22: Triad: 108055.3862
23: Triad: 114154.4542
24: Triad: 118730.5429
令我困惑的是 2-6 个进程的测量可持续带宽停滞不前。我认为使用过的处理器的 Turbo Boost 可能会影响结果。显然 Turbo Boost 仅在使用几个内核时才会激活,但我不确定如何正确解释结果。
要“关闭” Turbo Boost,一种可能是修改 STREAM 基准,如下所示:
- 始终使用所有 24 个可用内核以在整个基准测试过程中保持处理器负载大致恒定
- 将基准测试的 MPI 通信器拆分
MPI_COMM_WORLD
为两个独立的通信器。一个通信器将与实际运行基准测试的N个进程组相关联,另一组包含剩余的24-N 个进程,这些进程仅用于保持内核繁忙并防止 Turbo Boost - 24-N进程仅使用 L1 缓存中的数据,以尽量减少对其他进程的影响
- 将基准测试的运行时间延长到几分钟(Turbo Boost 效果持续时间不超过几秒钟?)
第一个实现仅使用三元组内核来处理应该适合 L1 缓存 (32kByte) 的数据集上的剩余24-N 个进程。Benchmark的重复次数提升至5000,数据数组长度大小提升至1*10^7。调用该函数foo
以防止(成功?)循环展开,前面的 if 条件false
贯穿整个程序执行。相关代码读取
if (rank < N) {
...
UNMODIFIED BENCHMARK
...
} else {
scalar=3.0;
for (i=0; i<10000000000; i++) {
for (j=0; j<1000; j++) a[j] = b[j]+scalar*c[j];
if (a[2] < 1.0) foo(a,b,c);
}
}
a、b 和 c 被声明为static double a[LEN],b[LEN],c[LEN]
main 之外。我还阅读了有关静态修饰符及其对基准测试的影响的讨论。我不确定是否foo
真的需要打电话。
不幸的是,我的方法并没有导致与基准测试不同的结果。
我的方法有什么问题?您是否了解替代方案,或者您对我应该如何修改我的基准有建议?
编辑:
由于一位用户对我用于基准测试的代码表现出兴趣:
我使用了 PETSc 附带的 STREAM 基准测试的修改版本:
在系统上安装 PETSc 后,您会在src/benchmarks/streams
如果你只对源代码感兴趣,你会在他们的 GitHub 页面上找到最新版本:
https://github.com/petsc/petsc/tree/master/src/benchmarks/streams