openMP和#pragma omp atomic

krz*_*kov 8 c++ parallel-processing atomic openmp

我有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;
}
Run Code Online (Sandbox Code Playgroud)

Hri*_*iev 9

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

x binop = expr
x ++
++ x
x -
- x

后来的版本包括x = x binop expr,但即使在VS2012中,MSVC也永远停留在OpenMP 2.0版本.仅作比较,目前的OpenMP版本为3.1,我们预计在接下来的几个月内会出现4.0.

在OpenMP 2.0中,您的语句应为:

#pragma omp atomic
sum += 4.0/(1.+ x*x);
Run Code Online (Sandbox Code Playgroud)

但正如已经注意到的那样,使用减少会更好(并且通常更快):

#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);  
}
Run Code Online (Sandbox Code Playgroud)

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