簡體   English   中英

通過openmp在C ++中並行化three_for_loop

[英]Parallelize three_for_loop in C++ by openmp

我有一個密碼。 在此,A,B,C,A1,B1,C1是3維矢量。 A,B,C相互獨立,而A1,B1,C1也相互獨立。 我想通過使用openmp進行並行計算。 但是,我用openmp運行它,出現“段錯誤”錯誤。您能幫我解決這個問題嗎? 先感謝您。

#include <omp.h>
#include<math.h> 
#include<cmath> 
#include<vector>    
#include<iostream>

using namespace std;
int main ()
{

int NX=801;              // NUmber of grid in X direction
int NY=501;              
int NZ=401;   
float PI=3.14159265358979323846;
unsigned int i,j,k;
vector<vector<vector<float> > > A (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
vector<vector<vector<float> > > B (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
vector<vector<vector<float> > > C (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
vector<vector<vector<float> > > A1 (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
vector<vector<vector<float> > > B1 (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
vector<vector<vector<float> > > C1 (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));

cout<<"start"<<endl;
#pragma omp parallel for private (j) shared(A,B,C,i,k,NX,NY,NZ) 
for (i=0;i<NX;i++)
    for (j=0;j<NY;j++)
        for (k=0;k<NZ;k++)
        {
            A[i][j][k]=sin(2.0*PI/float(NX*NY*NZ)*float(i*j*k));
            B[i][j][k]=cos(5.0*PI/float(NX*NY*NZ)*float(i*j*k));
            C[i][j][k]=sin(2.0*PI/float(NX*NY*NZ))*cos(5.0*PI/float(NX*NY*NZ)*float(i*j*k));
        }

#pragma omp parallel for private (j) shared(A1,B1,C1,A,B,C,i,k,NX,NY,NZ) 
for (i=1;i<NX-1;i++)
    for (j=1;j<NY-1;j++)
        for (k=1;k<NZ-1;k++)
        {
            A1[i][j][k]=C[i+1][j][k]*cos(5.0*PI/float(NX*NY*NZ)*float(i*j*k));
            B1[i][j][k]=A[i][j][k]+B[i][j][k]+C[i][j][k]*cos(5.0*PI/float(NX*NY*NZ)*float(i*j*k));
            C1[i][j][k]=16.0*A[i][j][k]*cos(5.0*PI/float(NX*NY*NZ)*float(i*j*k));
        }
cout<<"finish"<<endl;


return 0;
}

這段代碼很容易與OpenMP並行化。 但是,您在自己的嘗試中犯了一些錯誤,特別是嘗試聲明ik shared而實際上它們應該是private 更好的是,不要預先聲明變量,而只是在for循環中聲明它們。 這樣,它們將自動具有正確的范圍,從而防止您混淆它。

這是它會給的:

#include <omp.h>
#include<math.h> 
#include<cmath> 
#include<vector>    
#include<iostream>

using namespace std;
int main ()
{

    int NX=801;              // NUmber of grid in X direction
    int NY=501;              
    int NZ=401;   
    float PI=3.14159265358979323846;
    vector<vector<vector<float> > > A (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
    vector<vector<vector<float> > > B (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
    vector<vector<vector<float> > > C (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
    vector<vector<vector<float> > > A1 (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
    vector<vector<vector<float> > > B1 (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
    vector<vector<vector<float> > > C1 (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));

    cout<<"start"<<endl;
    #pragma omp parallel for
    for (int i=0;i<NX;i++)
        for (int j=0;j<NY;j++)
            for (int k=0;k<NZ;k++)
            {
                A[i][j][k]=sin(2.0*PI/float(NX*NY*NZ)*float(i*j*k));
                B[i][j][k]=cos(5.0*PI/float(NX*NY*NZ)*float(i*j*k));
                C[i][j][k]=sin(2.0*PI/float(NX*NY*NZ))*cos(5.0*PI/float(NX*NY*NZ)*float(i*j*k));
            }

    #pragma omp parallel for 
    for (int i=1;i<NX-1;i++)
        for (int j=1;j<NY-1;j++)
            for (int k=1;k<NZ-1;k++)
            {
                A1[i][j][k]=C[i+1][j][k]*cos(5.0*PI/float(NX*NY*NZ)*float(i*j*k));
                B1[i][j][k]=A[i][j][k]+B[i][j][k]+C[i][j][k]*cos(5.0*PI/float(NX*NY*NZ)*float(i*j*k));
                C1[i][j][k]=16.0*A[i][j][k]*cos(5.0*PI/float(NX*NY*NZ)*float(i*j*k));
            }
    cout<<"finish"<<endl;

    return 0;
}

現在,由於您要求並行化此代碼,所以我想您對性能感興趣。 因此,沒有什么可以阻止您實現這樣的一兩個非常基本的性能優化:

#include <omp.h>
#include<math.h> 
#include<cmath> 
#include<vector>    
#include<iostream>

using namespace std;
int main ()
{

    int NX=801;              // NUmber of grid in X direction
    int NY=501;              
    int NZ=401;   
    float PI=3.14159265358979323846;
    vector<vector<vector<float> > > A (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
    vector<vector<vector<float> > > B (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
    vector<vector<vector<float> > > C (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
    vector<vector<vector<float> > > A1 (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
    vector<vector<vector<float> > > B1 (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));
    vector<vector<vector<float> > > C1 (NX,vector<vector<float> >(NY,vector <float>(NZ,0.0)));

    const float PIOverSize = PI/(NX*NY*NZ);
    const float sin2PIOverSize = sin(2.0f*PIOverSize);
    cout<<"start"<<endl;
    double tbeg = omp_get_wtime();
    #pragma omp parallel
    {
    #pragma omp for
    for (int i=0;i<NX;i++)
        for (int j=0;j<NY;j++)
        {
            float IJPIOverSize=i*j*PIOverSize;
            for (int k=0;k<NZ;k++)
            {
                A[i][j][k]=sin(2.0f*IJPIOverSize*k);
                B[i][j][k]=cos(5.0f*IJPIOverSize*k);
                C[i][j][k]=sin2PIOverSize*cos(5.0f*IJPIOverSize*k);
            }
         }
    #pragma omp for 
    for (int i=1;i<NX-1;i++)
        for (int j=1;j<NY-1;j++)
        {
            float IJPIOverSize=i*j*PIOverSize;
            for (int k=1;k<NZ-1;k++)
            {
                A1[i][j][k]=C[i+1][j][k]*cos(5.0f*IJPIOverSize*k);
                B1[i][j][k]=A[i][j][k]+B[i][j][k]+C[i][j][k]*cos(5.0f*IJPIOverSize*k);
                C1[i][j][k]=16.0f*A[i][j][k]*cos(5.0f*IJPIOverSize*k);
            }
        }
    }
    double time = omp_get_wtime() - tbeg;
    cout<<"finish in "<<time<<" seconds"<<endl;

    return 0;
}

這樣,您的代碼應該已經更快了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM