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 - -wallhighlights pragma errors. example, when misspell- atomicfollowing 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