2

我想在集群的一个节点上运行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 基准测试的修改版本:

http://www.mcs.anl.gov/petsc/

在系统上安装 PETSc 后,您会在src/benchmarks/streams

如果你只对源代码感兴趣,你会在他们的 GitHub 页面上找到最新版本:

https://github.com/petsc/petsc/tree/master/src/benchmarks/streams

4

1 回答 1

1

您可以使用一些分析工具从外部测量当前的 cpu 时钟,该工具可以访问硬件性能监控单元以获取用于程序的 cpu 周期的实际计数。例如,linuxperfperf stat模式(或perf stat -e cpu-clock,cyclesperf stat -a -A系统范围内)执行此操作,它打印平均 CPU 频率与cycles它同时具有cycles事件计数和一些墙上时间事件(如task-clockor )时一致cpu-clock

我们可以通过读取墙上时间 (gettimeofday) 和读取周期性能计数器(但不是 RDTSC,因为大多数 TSC 现在是Invariant,“invariant TSC 由 CPUID.80000007H:EDX[8] 指示”)在内部计算它以进行编程。平均频率 = 周期消耗 / 花费时间。我们可以在测试功能之前和之后或在每个测试功能周围进行(如果启用了复制/缩放/添加流测试),以获得更详细的频率配置文件(有 HPC 跟踪项目,能够记录每个测试的时间和周期) MPI 调用)。

cpu 周期的内部读取(以计算程序片段的平均频率)可以使用一些 PMU api 完成,例如 perf_events(Linux,由 使用perf)、perfmon、libpfm3/libpfm4、PAPI或您在 HPC 部分中使用的其他 PMU 访问库世界。一些 PMU API 可以在操作系统和 CPU 架构之间移植。

或者,您可以尝试:禁用 Boost ( https://stackoverflow.com/a/38034503/196561 ) 或使用非常冷的水进行水冷永久启用它(可能不适用于 15+ 核心 Xeons 的世界)。

于 2016-06-26T01:54:13.767 回答