次のCコードでは、入れ子になったループでOpenMPを使用しています。競合状態が発生するので、私は最後にアトミック操作を実行します:コンパイラがOpenMPプラグマを無視するのはなぜですか?
double mysumallatomic() {
double S2 = 0.;
#pragma omp parallel for 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;
}
事が#pragma omp atomic
は、プログラムの動作に影響を与えないことである、私はそれを削除しても、何も起こりません。私が#pragma oh_my_god
に変更しても、エラーは発生しません!
私はOMPのプラグマをチェックするとき、私はより厳格であることをコンパイラに伝えることができるかどうか、ここで間違って起こっているのだろうか、私は最後の変更
PSを作る際に、なぜ私はエラーを取得しない:私は使用してコンパイルについて:
gcc-4.2 -fopenmp main.c functions.c -o main_elec_gcc.exe
PS2:私は同じ問題を与え、ガレスピーの考え方に基づいて新しいコード:
#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 for 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);
}
こんにちは、2)はい、私は削減前に使用しましたが、同じ問題です! 3)それで、還元も原子的助けもここでは何も起こっていないようです。 – flow
@Werner:私がアトミックを使うとき、私はいつも正しい答えを得ます。私の答えに私のコードを追加します – csgillespie
あなたのプログラムは効果的に動作します。以前のエラーは "a"と "b"を並列の内部で定義する必要があり、そのためにg ++コンパイラを使用する必要があることに気付きました。私がgccだけを使う前に。さて、私はあなたのコードを修正し、いくつかの新しいものを追加しました。あなたはPS2の質問の編集で見ることができるようになりましたが、今はg ++に対応した別の結果が得られます。私はあまりにも多くの操作をしているからですか? – flow