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

Posted

技术标签:

【中文标题】使用 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) 【发布时间】:2016-09-20 14:46:48 【问题描述】:

所以,我有现有的代码,其中几条指令通过简单地使用并行化

#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,从 3.1 到 4.0 的隐式 OpenMP 更改以及 4.0 的默认调度设置可能是调度问题的原因 (?)。

有没有办法像 OpenMP3.1 一样配置 OpenMP 4.0? 我发现例如

GOMP_CPU_AFFINITY
OMP_PROC_BIND
OMP_PARTS
...

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

我无法分享我的代码,因为它太大了,而且目前我没有可以分析它的最小示例,抱歉。

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

每条指令需要约 5 毫秒的单核处理时间,因此它们的运行速度非常快。 指令(A、B、C)是依次计算的 在启动 B 之前,执行等待所有 As 完成等(在 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 4 支持不应影响 OpenMP 3.1 构造的性能。随着内核数量的增加,设置关联性确实变得更加重要,尤其是在启用超线程的情况下。如果由于并行区域之间的顺序依赖关系而需要屏障,那么增加内核数量并不完全有效可能不足为奇。 额外的核心并不是我的重点——新的 CPU 有更多的缓存,每个核心都有更高的频率,但它并没有运行得更快(甚至更慢) 我同意@tim18。这里有多个因素:编译器版本、硬件……您是否考虑过在“旧”系统上构建静态二进制文件并在新系统上尝试一下? 【参考方案1】:

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

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

【讨论】:

以上是关于使用 OpenMP 4.0 (gcc 4.8.4) 而不是 OpenMP 3.1 (gcc 4.9.2) 时速度会降低的主要内容,如果未能解决你的问题,请参考以下文章

如何正确升级OpenMP版本?

通过 GCC 学习 OpenMP 框架

知道 OpenMP 4.0 会产生啥 SIMD 指令吗?

如何使用 GCC 5.1 和 OpenMP 将工作卸载到 Xeon Phi

Qt 4.8.4 mingw (gcc 4.7) 可以编译但不能运行

GCC 8.1.0/MinGW64 编译的 OpenMP 程序崩溃寻找 cygwin.s?