我正在使用OpenMP成功并行化我的c ++代码中的循环。我试过了 进一步使用OpenMP任务。不幸的是我的代码行为 真奇怪,所以我写了一个最小的例子,发现了一个问题。 我想定义几个任务。每个任务应该执行一次 通过一个空闲的线程。 不幸的是,我只能使所有线程执行每个任务或 只有一个线程按顺序执行所有任务。
这是我的代码基本上按顺序运行:
int main() {
#pragma omp parallel
{
int id, nths;
id = omp_get_thread_num();
#pragma omp single nowait
{
#pragma omp task
cout<<"My id is "<<id<<endl;
#pragma omp task
cout<<"My id is "<<id<<endl;
#pragma omp task
cout<<"My id is "<<id<<endl;
#pragma omp task
cout<<"My id is "<<id<<endl;
}
}
return 0;
}
只有工人0出现并给他的身份四次。
我希望看到“我的身份证是0;我的身份证是1;我的身份证是2;我的身份证是3;
如果我删除#pragma omp single
我得到16条消息,所有线程都会执行
每一个cout
。
这是我的OpenMP设置的问题还是我没有得到什么
任务?我在Ubuntu上使用gcc 6.3.0并正确使用-fopenmp
标志。
答案 0 :(得分:0)
您对OpenMP任务的基本用法(parallel
- &gt; single
- &gt; task
)是正确的,您误解了变量的数据共享属性的复杂性。
首先,您可以通过在任务中移动omp_get_thread_num()
而不是访问id
来轻松确认您的任务是由不同的线程运行。
您的示例中发生了什么,id
在private
构造中隐式parallel
。但是,在任务内部,它隐含firstprivate
。这意味着,该任务从执行single
构造的线程中复制值。对类似问题进行更详尽的讨论can be found here。
请注意,如果在嵌套任务构造中使用private
,则它与外部并行构造中的private
变量不同。简单地说,private
不是指线程,而是构造。这与threadprivate
的区别。但是,threadprivate
不是构造的属性,而是它自己的指令,仅适用于具有块范围的文件范围,命名空间范围或静态变量的变量。