OpenMP "master"杂注不得被"parallel for"杂注包围

the OpenMP "master" pragma must not be enclosed by the "parallel for" pragma

本文关键字:parallel for 包围 master OpenMP      更新时间:2023-10-16

为什么英特尔编译器不让我指定openmp 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;
}

编译错误C3034OpenMP 'master'指令不能直接嵌套在'parallel for'指令中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行时,主线程大多数时候都不存在。例如,让我们从Artyom:

中获取代码:
#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启动(主线程)。它到达的pragma实际上是在说"Master,执行下面的代码段"。作为主机,它可以运行这个函数。但是,当线程1、2或3等到达这段代码时会发生什么?

主指令是告诉当前/监听团队,主线程必须执行f()。但这个团队是一个单一的线程,没有主子在场。过了这个点,程序就不知道该怎么做了。

我认为这就是为什么master不允许出现在for循环中。

if (omp_get_thread_num() == 0)代替master directive可以工作,因为现在程序说,"如果你是大师,做这个。否则忽略"。