OpenMP and #pragma omp atomic

I have a problem with OpenMP. The MSVS compiler throws me "pragma omp atomic is irregular in shape". I do not know why. Code: (the program assigns a PI number using the integral method)

#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; } 
+6
source share
4 answers

Your program is perfectly syntactically correct OpenMP code according to current OpenMP standards (for example, it compiles unmodified using GCC 4.7.1), except that x must be declared private (which is not syntactic, but rather a semantic error). Unfortunately, Microsoft Visual C ++ implements the very old OpenMP specification (2.0 of March 2002), which allows the use of the following statements in the atomic construct:

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

Later versions included x = x binop expr, but MSVC was permanently stuck in OpenMP version 2.0 even in VS2012. In comparison, the current version of OpenMP is 3.1, and we expect 4.0 to appear in the coming months.

In OpenMP 2.0, your statement should look like this:

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

But as already noted, it would be better (and generally faster) to use the abbreviation:

 #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 can also write sum += 4.0/(1.+ x*x); )

+8
source

Try changing 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 as follows:

 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'm not sure if this fits your needs.

+1
source

Replace:

 #pragma omp atomic 

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

But I think reducing #pragma omp would be a better option since you have the sum + = Var;

Do the following:

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

You will probably need a #pragma summary more than a real solution to your problem.

#pragma is a collection of non-standard , specific compilers, and most of the time for a platform / system . that the behavior may differ on different machines with the same OS or just on machines with different settings - a set of functions for the preliminary processor.

As a result, any problem 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.

For standard C / C ++, #pragma does not exist.

0
source

All Articles