[英]Parallelization with openMP: shared and critical clauses
下面是通過openMP並行化的一部分代碼。 數組, ap[]
和sc[]
被賦予添加賦值,因此,我決定將它們共享,然后將它們放在critical
子句部分中,因為reduction
子句不接受數組。 但它給出了與其序列對應物不同的結果。 問題出在哪兒?
Vector PN, Pf, Nf; // Vector is user-defined structure
Vector NNp, PPp;
Vector gradFu, gradFv, gradFw;
float dynVis_eff, SGSf;
float Xf_U, Xf_H;
float mf_P, mf_N;
float an_diff, an_conv_P, an_conv_N, an_trans;
float sc_cd, sc_pres, sc_trans, sc_SGS, sc_conv_P, sc_conv_N;
float ap_trans;
#pragma omp parallel for
for (int e=0; e<nElm; ++e)
{
ap[e] = 0.f;
sc[e] = 0.f;
}
#pragma omp parallel for shared(ap,sc)
for (int f=0; f<nFaces; ++f)
{
PN = cntE[face_N[f]] - cntE[face_P[f]];
Pf = cntF[f] - cntE[face_P[f]];
Nf = cntF[f] - cntE[face_N[f]];
PPp = Pf - (Pf|norm(PN))*norm(PN);
NNp = Nf - (Nf|norm(PN))*norm(PN);
mf_P = mf[f];
mf_N = -mf[f];
SGSf = (1.f-ifac[f]) * SGSvis[face_P[f]]
+ ifac[f] * SGSvis[face_N[f]];
dynVis_eff = dynVis + SGSf;
an_diff = dynVis_eff * Ad[f] / mag(PN);
an_conv_P = -neg(mf_P);
an_conv_N = -neg(mf_N);
an_P[f] = an_diff + an_conv_P;
an_N[f] = an_diff + an_conv_N;
// cross-diffusion
sc_cd = an_diff * ( (gradVel[face_N[f]]|NNp) - (gradVel[face_P[f]]|PPp) );
#pragma omp critical
{
ap[face_P[f]] += an_N[f];
ap[face_N[f]] += an_P[f];
sc[face_P[f]] += sc_cd + sc_conv_P;
sc[face_N[f]] += -sc_cd + sc_conv_N;
}
您尚未聲明是否應共享並行子句中的所有其他變量。 您可以使用default
子句執行此操作。 如果未指定默認值,則變量全部共享,這會導致代碼中出現問題。
在你的情況下,我猜你應該去
#pragma omp parallel for default(none), shared(ap,sc,face_N,face_P,cntF,cntE,mf,ifac,Ad,an_P,an_N,SGSvis,dynVis), private(PN,Pf,Nf,PPp,NNp,mf_P,mf_N,SGSf,dynVis_eff,an_diff,an_conv_P,an_conv_N,sc_cd)
我強烈建議始終使用default(none)
以便編譯器在每次不明確聲明變量時都會抱怨並強制您明確地考慮它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.