用于区域线程关联的 OpenMP 并行

Posted

技术标签:

【中文标题】用于区域线程关联的 OpenMP 并行【英文标题】:OpenMP parallel for region thread affinity 【发布时间】:2013-02-06 02:32:18 【问题描述】:

假设我有以下 OpenMP 区域:

omp_set_num_threads(3);
#pragma omp parallel for

 //start
 ...
 //somewhere in the middle
 ...
 //end

假设我有 8 核系统。例如,在“开始”之后,假设线程 0 在核心 4 上运行,线程 1 在核心 5 上运行,线程 2 在核心 6 上运行。线程迁移从“结束”之前的“中间某处”是否可能他们各自的核心是在“开始”之后分配的? IE。是否有可能在“开始”之后将线程 0-2 分配给核心 4-5,而“中间某处”线程说分别迁移到核心 5-7?甚至有可能线程可能驻留在核心 0-2 上的“结束”之前?谢谢。

【问题讨论】:

如果您要求对线程的位置进行某种动态运行时控制,或者您只是询问原则上是否有可能将线程迁移到并行区域执行时不同的内核。 @HristoIliev 第二部分,我问的是原则上是否有可能线程迁移到不同的核心,而并行区域执行时没有明确要求这样做。谢谢。 @torem 记住:特权伴随着责任。也许你想在 cmets 上查看这个link(尤其是我什么时候不应该发表评论? @Massimiliano 对不起,如果我做错了什么。我只是想知道确切的情况。 【参考方案1】:

据我所知,OpenMP 3.1 规范没有提供任何重新绑定线程的方法。

事实上,控制线程绑定的唯一方法是通过OMP_PROC_BIND 环境变量:

OMP_PROC_BIND 环境变量设置全局 bind-var ICV 的值。此环境变量的值必须为 truefalse。如果环境变量设置为 true,则执行环境不应在处理器之间移动 OpenMP 线程。如果环境变量设置为 false,则执行环境可能会在处理器之间移动 OpenMP 线程。如果 OMP_PROC_BIND 的值既不是 true 也不是 false,则程序的行为由实现定义。

OpenMP 4.0 草案扩展了OMP_PROC_BIND 的可能值并添加了OMP_PLACES 环境变量,它允许选择线程如何绑定到资源。尽管如此,仍然没有重新绑定线程的标准方法。

如果您绝对需要这种行为,您可以考虑使用hwloc 库,尤其是CPU binding 部分。

【讨论】:

因此,在最后一部分中,它说 exec env 可能会在处理器之间移动 OpenMP 线程(当 OMP_PROC_BIND=false 时)。如果 OMP_PROC_BIND 既不是真的也不是假的,我怎么知道我的实现定义了什么?谢谢。 @torem,您应该查看编译器的文档以了解默认的 OpenMP 行为是什么。例如,当OMP_PROC_BIND 没有设置值时,GCC/libgomp 和 Intel OpenMP 都不会绑定线程。 @HristoIliev 非常感谢! @HristoIliev 我查看了gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc.pdf,也在 gcc.gnu.org/onlinedocs/libgomp.pdf,但没有关于 OMP_PROC_BIND。请问你能给我一个链接吗?例如,我的系统 gcc/gfortran --version 显示 4.7.2。非常感谢!!! 它的文档很糟糕,但您可以浏览源代码。如果OMP_PROC_BIND 设置为trueGOMP_CPU_AFFINITY 未设置,则线程以线性方式绑定:线程0 到CPU 0,线程1 到CPU 1,等等。如果还设置了GOMP_CPU_AFFINITY,它给出特定线程到核心的映射。如果OMP_PROC_BIND 未设置或设置为falseGOMP_CPU_AFFINITY 未设置,则关联机制未初始化。如果设置了GOMP_CPU_AFFINITY,则不管OMP_PROC_BIND是否设置,都会激活线程绑定。

以上是关于用于区域线程关联的 OpenMP 并行的主要内容,如果未能解决你的问题,请参考以下文章

OpenMp根据变量设置并行循环的线程数

openMP C++ 简单并行区域 - 输出不一致

在visual studio中运行OpenMP并行程序,设置的线程数NUM_THREADS与系统CPU线程数啥关系

我应该在 openMP 并行区域内使用 gnu 并行模式函数吗(for-loop,tasks)

openMP:并行运行所有线程会导致内存不足异常

openmp怎么用函数配置线程数