确定并行程序的 MFLOPS/s 效率

计算科学 并行计算 效率
2021-12-29 05:08:32

我正在运行一些科学(并行)代码,并希望获得一些性能分析测量。我想在理论上(峰值)性能的 flops/s 方面获得代码的“效率”。

我运行了一个简单的矩阵乘法示例(可以在网络上找到的 PAPI_flops.c)并使用 PAPI 测量计数获得测量结果。我使用的 HPC 系统(56 Gb/s 互连)有这个 cpuinfo:

processor   : 39
vendor_id   : GenuineIntel
cpu family  : 6
model       : 62
model name  : Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz
stepping    : 4
microcode   : 1064
cpu MHz     : 1200.000
cache size  : 25600 KB
physical id : 1
siblings    : 20
core id     : 12
cpu cores   : 10
apicid      : 57
initial apicid  : 57
fpu     : yes
fpu_exception   : yes
cpuid level : 13

设 A 和 B 为 1000x1000 矩阵,带有随机浮点数。对于串行过程,我将 A 乘以 B 后得到以下指标:

Real_time:  3.340896
Proc_time:  3.344447
Total flpins:   2837232042
MFLOPS:     848.341187

现在,据我了解,理论上的峰值性能将是#cores x clock x FLOPs/cycle。我相信上面的处理器可以做 4 FLOPs/cycle,所以如果我假设我有一个单核 2.8 GHz 处理器,理论性能大约是 11200 MFLOPS。这会给我大约7%的效率......

那是极低的效率。850 MFLOPS 对我来说似乎是一个相当不错的高性能速率。我在这里做错了什么,还是像矩阵乘法这样简单的事情?

3个回答

您错过的因素是,当您进行矩阵矩阵乘法时,您必须从内存中重新加载数据。由于您的矩阵足够大以至于它们无法放入缓存中,因此您访问的主内存与浮点运算相比非常慢。让您了解一下有多慢:当今典型处理器上的浮点乘法需要 1.5ns,而从主存储器加载浮点数需要 60-100ns。

换句话说,芯片的浮点性能对于大小为 1000×1000 的矩阵无关紧要。这完全与内存带宽和延迟有关。

对于稠密矩阵或阶,矩阵乘积所需的理论 FLOPS 数为在您的情况下,由于您将两个 1000 阶矩阵相乘,因此在 MFLOPS 中,FLOPS 的数量应该是 2000。因此,您的代码的 848.3 MFLOPS 性能不到矩阵乘法理论性能的 50%。n2n3

缩放,如果您使用良好的乘法算法(递归、缓存感知算法比依赖线性代数中的矩阵乘法公式的普通算法要好得多),您应该会看到(或至少期望)更好的性能。n

但是,这里值得注意的是,FLOP 计数只是对性能的粗略估计:当您使用它来评估程序的效率时,您显然忽略了许多影响程序执行的开销因素。因此,FLOP 计数只能捕捉程序效率的一个特定维度。

自从 Intel Westmere 以来,您无法使用硬件性能计数器来测量我们认为准确的触发器。计数器对发出的未执行或已退出的操作进行计数。因此,如果您需要从内存中加载一些数据并且有一个等待它返回的停顿,则该指令可能会在完成之前多次重新发出。我们在 E5-2650 v1(即 SandyBridge)上看到了高达 10 倍的超算,IvyBridge 和 Haswell 也是如此。如果你想计算翻牌,你必须在你的例程中手工计算它们,而不是使用硬件计数器。