C++ 嵌套循环中未正确忽略内部循环的Pragma omp parallel
我试图实现以下代码,以了解如何通过嵌套循环管理OpenMP线程,其中每个内部/外部循环在函数及其调用方中分别实现 每个循环都用语句实现C++ 嵌套循环中未正确忽略内部循环的Pragma omp parallel,c++,multithreading,openmp,C++,Multithreading,Openmp,我试图实现以下代码,以了解如何通过嵌套循环管理OpenMP线程,其中每个内部/外部循环在函数及其调用方中分别实现 每个循环都用语句实现 #pragma omp parallel for,我假设忽略了内部循环的pragma 为了看到这一点,我在每个循环中打印了线程编号 然后,我可以看到以下内容,其中内部循环中的线程id始终为零,与调用方对应的线程编号不相同。为什么会发生这种情况 Calling 0 from 0 Calling 2 from 1 Calling 6 from 4 Calling 8
#pragma omp parallel for
,我假设忽略了内部循环的pragma
为了看到这一点,我在每个循环中打印了线程编号
然后,我可以看到以下内容,其中内部循环中的线程id始终为零,与调用方对应的线程编号不相同。为什么会发生这种情况
Calling 0 from 0
Calling 2 from 1
Calling 6 from 4
Calling 8 from 6
Calling 4 from 2
Calling 7 from 5
Calling 5 from 3
Calling 0 from 0 // Expecting 3
Calling 1 from 0
Calling 2 from 0
Calling 3 from 0
Calling 0 from 0
Calling 1 from 0
Calling 2 from 0
Calling 3 from 0
Calling 0 from 0
Calling 0 from 0
Calling 0 from 0
Calling 1 from 0
Calling 2 from 0
Calling 3 from 0
Calling 9 from 7
Calling 1 from 0 // Expecting 7
Calling 2 from 0
Calling 3 from 0
Calling 0 from 0
Calling 3 from 1
Calling 0 from 0 // Expecting 1
Calling 1 from 0
Calling 2 from 0
Calling 1 from 0
Calling 2 from 0
Calling 3 from 0
Calling 3 from 0
Calling 1 from 0
Calling 2 from 0
Calling 3 from 0
Calling 0 from 0
Calling 1 from 0
Calling 2 from 0
Calling 3 from 0
Calling 0 from 0
Calling 1 from 0
Calling 2 from 0
Calling 3 from 0
Calling 1 from 0
Calling 0 from 0
Calling 1 from 0
Calling 2 from 0
Calling 3 from 0
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
const size_t kM=4;
结构垫
{
国际元素[kM];
材料(施工材料和副本)
{
for(size_t i=0;ielem[i]=copy.elem[i];
}
Mat()
{
对于(size_t i=0;i,除非您为OpenMP提供特殊选项,否则它会尝试在编译时分割工作,而嵌套并行很难实现,因此它甚至不会尝试
您可以参考以获取建议(例如,在OpenMP 3.0+中使用折叠,我不确定我是否理解您的期望,但您得到的结果完全符合预期
默认情况下,OpenMP嵌套并行被禁用,这意味着任何嵌套的并行
区域将创建一个线程组,其数量与外部级别遇到它们的线程数量相同
在您的例子中,最外层的并行
区域创建一个由8个线程组成的团队。每个线程都将到达最内层的并行
区域,并创建一个第二级1线程团队。每个第二级线程在其自己的团队中排名为0,因此打印的0为0
对于使用g++9.3.0编译的完全相同的代码,通过设置两个环境变量OMP_NUM_THREADS
和OMP_NESTED
,我得到以下结果:
OMP_NUM_THREADS="2,3" OMP_NESTED=true ./a.out
Calling 0 from 0
Calling 5 from 1
Calling 0 from 0
Calling 1 from 0
Calling 2 from 1
Calling 0 from 0
Calling 1 from 0
Calling 3 from 2
Calling 3 from 2
Calling 2 from 1
Calling 6 from 1
Calling 1 from 0
Calling 0 from 0
Calling 1 from 0
Calling 3 from 2
Calling 2 from 1
Calling 2 from 0
Calling 0 from 0
Calling 1 from 0
Calling 2 from 1
Calling 3 from 2
Calling 0 from 0
Calling 1 from 0
Calling 3 from 2
Calling 2 from 1
Calling 3 from 0
Calling 7 from 1
Calling 0 from 0
Calling 3 from 2
Calling 2 from 1
Calling 3 from 2
Calling 0 from 0
Calling 1 from 0
Calling 1 from 0
Calling 2 from 1
Calling 4 from 0
Calling 8 from 1
Calling 0 from 0
Calling 3 from 2
Calling 2 from 1
Calling 2 from 1
Calling 0 from 0
Calling 1 from 0
Calling 3 from 2
Calling 1 from 0
Calling 9 from 1
Calling 2 from 1
Calling 0 from 0
Calling 1 from 0
Calling 3 from 2
也许这更符合您的预期?内部循环中显示的数字的含义是什么?在我的例子中,所有内容都显示为0。但是,我们有8个线程并行执行外部循环(数字0-7)。我怀疑内部循环是否由编号为0的同一线程处理。您的误解可能是因为omp\u thread\u num()
返回了最近遇到的团队(最内部的团队)中的线程id,不一定是第一个。因此,您看到的0与此完全一致,因为所有线程都是第二级并行区域上的主线程,每个区域有8个不同的团队,每个团队有1个线程。在我的版本中,我们创建了2个第二级团队,每个团队有3个线程。这就是为什么您看到ID从0到2的原因。这有意义吗?啊,I g说到这里。谢谢你的评论。当我删除了内部循环的pragma语句时,我的期望值就来了。这是否意味着在内部/外部循环中使用omp parallel for
语句(没有任何特定选项)会在内部循环中产生额外的开销?