OpenMP“master”编译指令不能被“parallel for”编译指令包含
问题描述:
为什么intel编译器不能让我指定只应由主线程执行openmp parallel for
块中的某些动作?OpenMP“master”编译指令不能被“parallel for”编译指令包含
如果没有这种功能,我该怎么做?
我试图做的是更新通过回调的进度条在平行于:
long num_items_computed = 0;
#pragma omp parallel for schedule (guided)
for (...a range of items...)
{
//update item count
#pragma omp atomic
num_items_computed++;
//update progress bar with number of items computed
//master thread only due to com marshalling
#pragma omp master
set_progressor_callback(num_items_computed);
//actual computation goes here
...blah...
}
我想只有主线程调用回调,因为如果我不强制执行(比如通过使用omp critical
代替,以保证只有一个线程使用回调一次)我得到以下运行时异常:
The application called an interface that was marshalled for a different thread.
...因此,让所有的回调在主线程的愿望。
在此先感谢。
答
#include <omp.h>
void f(){}
int main()
{
#pragma omp parallel for schedule (guided)
for (int i = 0; i < 100; ++i)
{
#pragma omp master
f();
}
return 0;
}
编译器错误C3034 OpenMP的 '主人' 指令不能直接嵌套在 '平行的' 指令 Visual Studio 2010中的OpenMP 2.0
可能是这样:
long num_items_computed = 0;
#pragma omp parallel for schedule (guided)
for (...a range of items...)
{
//update item count
#pragma omp atomic
num_items_computed++;
//update progress bar with number of items computed
//master thread only due to com marshalling
//#pragma omp master it is error
//#pragma omp critical it is right
if (omp_get_thread_num() == 0) // may be good
set_progressor_callback(num_items_computed);
//actual computation goes here
...blah...
}
答
之所以你得到的错误是因为主线程在代码到达#pragma omp master
行时大部分时间都没有。 例如,让我们的代码从阿尔乔姆:
#include <omp.h>
void f(){}
int main()
{
#pragma omp parallel for schedule (guided)
for (int i = 0; i < 100; ++i)
{
#pragma omp master
f();
}
return 0;
}
如果代码将编译,下面会发生:
假设线程0开始(主线程)。它达到了实际上说“主人,做下面的一段代码”的编译指示。它是主人可以运行的功能。 但是,当线程1或2或3等达到那段代码时会发生什么?
主指令告诉当前/收听团队主线程必须执行f()
。但团队是一个单一的线程,并没有主人在场。该方案不知道过去该做什么。
这就是为什么我认为主人不允许进入for循环。
将master directive
替换为if (omp_get_thread_num() == 0)
是可行的,因为现在程序会说“如果您是主人,请执行此操作,否则忽略”。
这似乎是工作,谢谢。我担心主线程可能与所有工作线程不同......因此回调将永远不会执行......在omp规范中是可以想象的吗? –
如果迭代次数很大,则不会注意到差异。并且在循环之后添加:if(omp_get_thread_num()== 0)set_progressor_callback(num_items_computed); –
from standart OpenMP about pragma omp parallel for():“循环结构指定一个或多个关联循环的迭代将由团队中的线程在其隐式任务的上下文中并行执行。迭代分布在执行循环区域绑定的并行区域的团队中已存在的线程上。“ –