当使用OpenMP 4.0 (gcc 4.8.4)而不是OpenMP 3.1 (gcc 4.9.2)时,速度会降低

Speed decreases when using OpenMP 4.0 (gcc 4.8.4) instead of OpenMP 3.1 (gcc 4.9.2)

本文关键字:gcc OpenMP 速度      更新时间:2023-10-16

所以,我有几个指令并行的代码,通过使用简单的

#pragma omp parallel for schedule( static, 1 )
[instruction set A with 4 instructions -> 4 threads]
#pragma omp parallel for schedule( static, 1 )
[instruction set B with 4 instructions -> 4 threads]
#pragma omp parallel for schedule( static, 1 )
[instruction set C with 4 instructions -> 4 threads]

代码在4核i5机器上执行得非常快,CPU核心使用率几乎一直是100%。

线程被很好地调度,即:

Core 1 handles instruction A1 -> B1 -> C1
Core 2 handles instruction A2 -> B2 -> C2 
Core 3 handles instruction A3 -> B3 -> C3 

这很重要,因为例如指令B1依赖于指令A1等的数据。

但是,我有一台新机器(具有更快的6核CPU),程序执行速度较慢。

我目前最好的机会是,调度在这种情况下没有那么好。

由于我也将编译器从gcc 4.8.4更改为4.9.2,隐含的openmp从3.1更改为4.0和4.0的默认调度设置可能是调度问题的原因(?)。

是否有一种方法可以配置openmp4.0,它就像OpenMP3.1一样调度?例如:

GOMP_CPU_AFFINITY
OMP_PROC_BIND
OMP_PARTS
...

我只是没有找到任何提示如何使4.0和3.1的行为相似…

我不能分享我的代码,因为它太大了,目前,我没有一个最小的例子,我可以分析它,对不起。

更新:这样的指示可能不是原因,因为它以前起过作用。我能告诉你的是:

  • 每条指令需要约5ms的单核处理时间,所以它们运行得非常快。
  • 指令(A, B, C)一个接一个计算
  • 在启动B之前,等待所有a完成,等等(在启动C之前,所有B必须完成)
  • 对于每条指令,并行计算3个SIMD线程(例如A1, A2, A3)
  • 每个指令A, B, C都依赖于它们的前辈的数据(例如B1使用来自A1的数据,但没有来自任何"2"或"3"指令的数据,应该在不同的内核上运行)

我想要的是一个核心绑定,这样

Core 1 handles instruction A1 -> B1 -> C1
Core 2 handles instruction A2 -> B2 -> C2 
Core 3 handles instruction A3 -> B3 -> C3 

经过长时间的调试并试图确定问题,我能够修复它:

这不是OpenMP的问题,而是硬件的问题。在进程运行时,操作系统明显降低了CPU频率(从3900MHz降至1200MHz),甚至。当我在BIOS中禁用所有CPU节能设置时,该进程以预期的速度运行。仅供参考:英特尔i7-5930K,华硕x99 - ews。