c - Why does the compiler ignore OpenMP pragmas? -
in following c code using openmp in nested loop. since race condition occurs, want perform atomic operations @ end:
double mysumallatomic() { double s2 = 0.; #pragma omp parallel shared(s2) for(int a=0; a<128; a++){ for(int b=0; b<128;b++){ double myterm = (double)a*b; #pragma omp atomic s2 += myterm; } } return s2; }
the thing #pragma omp atomic
has no effect on program behaviour, if remove it, nothing happens. if change #pragma oh_my_god
, no error!
i wonder going wrong here, whether can tell compiler more strict when checking omp pragmas or why not error when make last change
ps: compilation use:
gcc-4.2 -fopenmp main.c functions.c -o main_elec_gcc.exe
ps2: new code gives me same problem , based on gillespie idea:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <omp.h> #include <math.h> #define nrack 64 #define nstars 1024 double mysumallatomic_serial(float rocks[nrack][3], float moon[nstars][3], float qr[nrack],float ql[nstars]) { int j,i; float temp_div=0.,temp_sqrt=0.; float difx,dify,difz; float mod2x, mod2y, mod2z; double s2 = 0.; for(j=0; j<nrack; j++){ for(i=0; i<nstars;i++){ difx=rocks[j][0]-moon[i][0]; dify=rocks[j][1]-moon[i][1]; difz=rocks[j][2]-moon[i][2]; mod2x=difx*difx; mod2y=dify*dify; mod2z=difz*difz; temp_sqrt=sqrt(mod2x+mod2y+mod2z); temp_div=1/temp_sqrt; s2 += ql[i]*temp_div*qr[j]; } } return s2; } double mysumallatomic(float rocks[nrack][3], float moon[nstars][3], float qr[nrack],float ql[nstars]) { float temp_div=0.,temp_sqrt=0.; float difx,dify,difz; float mod2x, mod2y, mod2z; double s2 = 0.; #pragma omp parallel shared(s2) for(int j=0; j<nrack; j++){ for(int i=0; i<nstars;i++){ difx=rocks[j][0]-moon[i][0]; dify=rocks[j][1]-moon[i][1]; difz=rocks[j][2]-moon[i][2]; mod2x=difx*difx; mod2y=dify*dify; mod2z=difz*difz; temp_sqrt=sqrt(mod2x+mod2y+mod2z); temp_div=1/temp_sqrt; float myterm=ql[i]*temp_div*qr[j]; #pragma omp atomic s2 += myterm; } } return s2; } int main(int argc, char *argv[]) { float rocks[nrack][3], moon[nstars][3]; float qr[nrack], ql[nstars]; int i,j; for(j=0;j<nrack;j++){ rocks[j][0]=j; rocks[j][1]=j+1; rocks[j][2]=j+2; qr[j] = j*1e-4+1e-3; //qr[j] = 1; } for(i=0;i<nstars;i++){ moon[i][0]=12000+i; moon[i][1]=12000+i+1; moon[i][2]=12000+i+2; ql[i] = i*1e-3 +1e-2 ; //ql[i] = 1 ; } printf(" serial: %f\n", mysumallatomic_serial(rocks,moon,qr,ql)); printf(" openmp: %f\n", mysumallatomic(rocks,moon,qr,ql)); return(0); }
using flag
-wall
highlights pragma errors. example, when misspellatomic
following warning.main.c:15: warning: ignoring #pragma omp atomic1
i'm sure know, in case, example should handled
reduction
when use omp parallel, default variables shared. not want in case. example, each thread have different value
difx
. instead, loop should be:#pragma omp parallel default(none),\ private(difx, dify, difz, mod2x, mod2y, mod2z, temp_sqrt, temp_div, i, j),\ shared(rocks, moon, ql, qr), reduction(+:s2) for(j=0; j<nrack; j++){ for(i=0; i<nstars;i++){ difx=rocks[j][0]-moon[i][0]; dify=rocks[j][1]-moon[i][1]; difz=rocks[j][2]-moon[i][2]; mod2x=difx*difx; mod2y=dify*dify; mod2z=difz*difz; temp_sqrt=sqrt(mod2x+mod2y+mod2z); temp_div=1/temp_sqrt; s2 += ql[i]*temp_div*qr[j]; } }
Comments
Post a Comment