你好我是c ++的新手,我制作了一个运行的代码,但由于许多嵌套的for循环它很慢,我想通过openmp加速它,任何可以指导我的人。我尝试在 ip 循环之前使用' #pragma omp parallel ',在此循环中我使用' #pragma omp parallel for '之前它循环但它不起作用
#pragma omp parallel
for(int ip=0; ip !=nparticle; ip++){
inf14>>r>>xp>>yp>>zp;
zp/=sqrt(gamma2);
counter++;
double para[7]={0,0,Vz,x0-xp,y0-yp,z0-zp,0};
if(ip>=0 && ip<=43){
#pragma omp parallel for
for(int it=0;it<NT;it++){
para[6]=PosT[it];
for(int ix=0;ix<NumX;ix++){
para[3]=PosX[ix]-xp;
for(int iy=0;iy<NumY;iy++){
para[4]=PosY[iy]-yp;
for(int iz=0;iz<NumZ;iz++){
para[5]=PosZ[iz]-zp;
int position=it*NumX*NumY*NumZ+ix*NumY*NumZ+iy*NumZ+iz;
rotation(para,&Field[3*position]);
MagX[position] +=chg*Field[3*position];
MagY[position] +=chg*Field[3*position+1];
MagZ[position] +=chg*Field[3*position+2];
}
}
}
}
}
}enter code here
我的旋转函数也有无限积分循环,如下所示
for(int i=1;;i++){
gsl_integration_qag(&F, 10*i, 10*i+10, 1.0e-8, 1.0e-8, 100, 2, w, &temp, &error);
result+=temp;
if(abs(temp/result)<ACCURACY){
break;
}
}
我也在使用gsl库。那么如何加快这个过程或如何制作openmp?
答案 0 :(得分:0)
不要在另一个并行编译指示中设置并行编译指示。您可能会在机器上方创建更多线程而不是它可以处理的线程我会在outter循环中建立并行化(如果它足够大):
#pragma omp parallel for
for(int ip=0; ip !=nparticle; ip++)
还要确保线程之间没有任何race condition(例如RAW)。
建议:如果你没有获得很好的加速,一个好的做法是按块进行迭代,而不仅仅是一个增量。例如:
int num_threads = 1;
#pragma omp parallel
{
#pragma omp single
{
num_threads = omp_get_num_threads();
}
}
int chunkSize = 20; //Define your own chunk here
for (int position = 0; position < total; position+=(chunkSize*num_threads)) {
int endOfChunk = position + (chunkSize*num_threads);
#pragma omp parallel for
for(int ip = position; ip < endOfChunk ; ip += chunkSize) {
//Code
}
}
答案 1 :(得分:0)
如果您不具有循环间依赖关系,则可以使用collapse
关键字并行化多个循环altoghether。例如:
void scale( int N, int M, float A[N][M], float B[N][M], float alpha ) {
#pragma omp for collapse(2)
for( int i = 0; i < N; i++ ) {
for( int j = 0; j < M; j++ ) {
A[i][j] = alpha * B[i][j];
}
}
}
我建议你查看OpenMP C/C++ cheat sheet (PDF),其中包含循环并行化的所有规范。