C++ OpenMP 和 #pragma omp atomic

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14016026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:53:56  来源:igfitidea点击:

OpenMP and #pragma omp atomic

c++parallel-processingopenmpatomic

提问by krzakov

I have an issue with OpenMP. MSVS compilator throws me "pragma omp atomic has improper form". I don't have any idea why. Code: (program appoints PI number using integrals method)

我有一个 OpenMP 问题。MSVS 编译器向我抛出“pragma omp atomic 形式不正确”。我不知道为什么。代码:(程序用积分法指定PI号)

#include <stdio.h>
#include <time.h>
#include <omp.h>

long long num_steps = 1000000000;
double step;

int main(int argc, char* argv[])
{
    clock_t start, stop;
    double x, pi, sum=0.0;
    int i;
    step = 1./(double)num_steps;
    start = clock();

    #pragma omp parallel for
    for (i=0; i<num_steps; i++)
    { 
        x = (i + .5)*step;
        #pragma omp atomic //this part contains error
        sum = sum + 4.0/(1.+ x*x);  
    }

    pi = sum*step;
    stop = clock();

    // some printf to show results
return 0;
}

回答by Hristo Iliev

Your program is a perfectly syntactically correct OpenMP code by the current OpenMP standards (e.g. it compiles unmodified with GCC 4.7.1), except that xshould be declared private(which is not a syntactic but rather a semantic error). Unfortunately Microsoft Visual C++ implements a very old OpenMP specification (2.0 from March 2002) which only allows the following statements as acceptable in an atomicconstruct:

根据当前的 OpenMP 标准,您的程序是句法上完全正确的 OpenMP 代码(例如,它使用 GCC 4.7.1 编译时未经修改),但x应该声明的除外private(这不是句法错误,而是语义错误)。不幸的是,Microsoft Visual C++ 实现了一个非常古老的 OpenMP 规范(2002 年 3 月的 2.0),它只允许在atomic构造中接受以下语句:

xbinop= expr
x++
++x
x--
--x

xbinop= expr
x++
++ x
x--
-- x

Later versions included x= xbinop expr, but MSVC is forever stuck at OpenMP version 2.0 even in VS2012. Just for comparison, the current OpenMP version is 3.1 and we expect 4.0 to come up in the following months.

后来的版本包括x= xbinop expr,但即使在 VS2012 中,MSVC 也永远停留在 OpenMP 2.0 版。只是为了比较,当前的 OpenMP 版本是 3.1,我们预计 4.0 将在接下来的几个月中推出。

In OpenMP 2.0 your statement should read:

在 OpenMP 2.0 中,您的声明应为:

#pragma omp atomic
sum += 4.0/(1.+ x*x);

But as already noticed, it would be better (and generally faster) to use reduction:

但正如已经注意到的,使用reduce会更好(通常更快):

#pragma omp parallel for private(x) reduction(+:sum)
for (i=0; i<num_steps; i++)
{ 
    x = (i + .5)*step;
    sum = sum + 4.0/(1.+ x*x);  
}

(you could also write sum += 4.0/(1.+ x*x);)

(你也可以写sum += 4.0/(1.+ x*x);

回答by NiVeR

Try to change sum = sum + 4.0/( 1. + x*x )to sum += 4.0/(1.+ x*x), But I'm afraid this won't work either. You can try to split the work like this:

尝试更改sum = sum + 4.0/( 1. + x*x )sum += 4.0/(1.+ x*x),但恐怕这也行不通。您可以尝试像这样拆分工作:

x = (i + .5)*step;
double xx = 4.0/(1.+ x*x);
#pragma omp atomic //this part contains error
sum += xx;

this should work, but I am not sure whether it fits your needs.

这应该有效,但我不确定它是否符合您的需求。

回答by Aizen

Replace :

代替 :

#pragma omp atomic

by #pragma omp reduction(+:sum)or #pragma omp critical

通过#pragma omp reduction(+:sum)#pragma omp critical

But I guess #pragma omp reduction will be a better option as you have sum+=Var;

但我想 #pragma omp reduction 将是一个更好的选择,因为你有 sum+=Var;

Do like this:

这样做:

x = (i + .5)*step;
double z = 4.0/(1.+ x*x);
#pragma omp reduction(+:sum)
sum += z;

回答by user1824407

You probably need a recap about #pragmamore than the real solution to your problem.

您可能需要回顾的#pragma不仅仅是问题的真正解决方案。

#pragmaare a set of non-standard, compiler specific, and most of the time, platform/system specific- meaning that the behaviour can be different on different machines with the same OS or simply on machines with different setups - set of instrunctions for the pre-processor.

#pragma是一组非标准的特定于编译器的,并且大多数情况下是特定平台/系统的——这意味着行为在具有相同操作系统的不同机器上或只是在具有不同设置的机器上可能不同——用于预-处理器。

As consequence any issue with pragma can be solved only if you look at the official documentation for your compiler for your platform of choice, here are 2 links.

因此,只有查看所选平台的编译器的官方文档,才能解决 pragma 的任何问题,这里有 2 个链接。

For the standard C/C++ #pragmadoesn't exist.

对于标准 C/C++#pragma不存在。