我想在群集的一个节点上运行MPI Version STREAM benchmark来测量不同数量的MPI进程的可持续带宽。每个节点由两个Intel®Xeon®处理器E5-2680 v3 (12个内核)组成。
在下文中,我将使用openmpi v.1.8.2和选项map-by core
以 triad 测试的MByte / s结果显示结果。源代码是使用
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基准:
MPI_COMM_WORLD
分成两个独立的。一个通信器将与实际运行基准测试的 N 进程组相关联,另一个组包含剩余的 24-N 进程,这些进程仅用于保留核心忙碌并阻止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在main之外声明为static double a[LEN],b[LEN],c[LEN]
。我还阅读了this关于静态修饰符及其对基准的影响的讨论。我不确定是否真的需要调用foo
。
不幸的是,我的方法没有导致基准测试的结果不同。
我的做法有什么问题? 您是否了解替代方案,或者您对如何修改基准测试有什么建议?
修改
由于一位用户对我用于基准测试的代码表现出兴趣:
我在PETSc中使用了STREAM基准测试的修改版本:
在系统上安装PETSc后,您可以在src/benchmarks/streams
如果您只对源代码感兴趣,可以在GitHub页面上找到最新版本:
https://github.com/petsc/petsc/tree/master/src/benchmarks/streams
答案 0 :(得分:1)
您可以使用一些分析工具在外部测量当前的cpu时钟,该工具可以访问硬件性能监视单元以获得用于程序的cpu周期的实际计数。例如,linux perf
以perf stat
模式(或perf stat -e cpu-clock,cycles
或perf stat -a -A
为系统范围)执行此操作,它会根据cycles
打印平均CPU频率当它同时计算了cycles
个事件和一些像task-clock
或cpu-clock
这样的等待时间事件时。
我们可以通过读取壁时间(gettimeofday)和读取周期性能计数器(但不是RDTSC,因为大多数TSC现在是Invariant)在内部计算这个,“不变TSC由CPUID.80000007H表示:EDX [ 8]“)。 Mean_Frequency = cycles_consumed / spent_time。我们可以在测试功能之前和之后,或者在每个测试功能之后(如果启用了复制/缩放/ ADD流测试),以获得更详细的频率曲线(有HPC跟踪项目,能够记录每个时间和周期) MPI致电)。
cpu周期的内部读取(计算程序片段的平均频率)可以通过一些PMU api来完成,例如perf_events(Linux,这由perf
使用),perfmon,libpfm3 / libpfm4,您在HPC世界中使用的PAPI或其他PMU访问lib。一些PMU API可在OS和CPU架构之间移植。
或者,您可以尝试:禁用Boost(https://stackoverflow.com/a/38034503/196561)或使用非常凉爽的水冷却永久启用它(在15+核心Xeons的世界中可能无效)。