首页 > 解决方案 > 当我在 openmp 循环中调用 C++ 类方法时出现奇怪的结果

问题描述

大家早上好。

我制作了一个在单线程模式下运行的代码,我正试图在多线程模式下对其进行调整。我在单线程模式下运行与 MARCH::RUN_PAR 非常相似的方法,结果很好,但是当我尝试在多线程模式下执行(使用 Openmp)时,结果太奇怪了。

有人可以帮我解决这个问题吗?

按照下面我的一段代码:

void MI_MARCH::RUN_PARALELO(double zt,double ***Vpar,int mt,int red_yred,int prof,int tam) {

        int RANK, numero_proc_parall;
        int shift,cont,m,rredy;
        //start the number of (possible) threads
        numero_proc_parall = tam;   
        //shift the loop of threads
        shift = 0;
        //the necessary total number of threads
        cont = prof;
        //set the number of threads
        omp_set_num_threads(numero_proc_parall);    
        //argument initialization    
        rredy = red_yred;   

        MARCH VETOR_MARCH[numero_proc_parall];  //vector of class   

        //open the parallel section
        #pragma omp parallel shared(cont,shift,numero_proc_parall) private(red_yred,RANK,m)
        {

            while(cont > 0)
            {

                #pragma omp critical
                std::cout<<"[MI_MARCH RUN_PAR] loop cont "<<cont<<" shift "<<shift<<" numero_proc_parall "<<numero_proc_parall<<"\n";           
                #pragma omp for
                for(m=0;m<numero_proc_parall;m++) //loop de profundidade
                {
                    //atualize the rank 
                    RANK = omp_get_thread_num();
                    //set the reference
                    red_yred = rredy + m + shift            
                    //run the method of the MARCH class
                    VETOR_MARCH[m].RUN_PAR(zt,Vpar[m],mt,red_yred,RANK + shift);                
                }   
                //execute only in the master thread
                #pragma omp master
                {
                    //increment the shift variable
                    shift = shift + numero_proc_parall;
                    //decrement the loop control
                    cont = cont - numero_proc_parall;
                    //verify if the process is greater than controller  
                    if(cont<numero_proc_parall)
                    {
                        //set a new number of parallel process
                        numero_proc_parall = cont;
                    }                               
                }
                #pragma omp barrier //waiting other process
            }       
        }
    }   

MARCH::RUN_PAR 方法是:

    void MARCH::RUN_PAR(double zt,double **Vxy,int mt,int red_yred,int RANK);
    {

        int xf,yf;    
        xf = 100;
        yf = 100; 

        //execute this piece of code in critical mode
        #pragma omp critical
        {       

            for(int i=0;i<xf;i++)
            {
                 for(int j=0;j<yf;j++)
                {           
                    Vcopia[i][j] = Vxy[i][j];  //Vcopia is a member of MARCH class
                }
            }

        }

        V_H(Vcopia,xf,yf,red_yred); //this method is a member of MARCH class

        CALC(mt,zt,RANK); //this method is a member of MARCH class

    }

...
    class MARCH{
    public: 
    ...
      void RUN_PAR(double zt,double **Vxy,int mt,int red_yred,int RANK);

    private:    
    ...
      double **Vcopia;
    ...
      void V_H(double **Vcopia,int xf,int yf,int red_yred); 

      void CALC(int mt,double zt,int RANK); 
    };

显然,不正确的结果以顺序模式出现。

单线程模式下的正确结果是这样的图像:正确的图像

不正确的使用多个线程是这样的图像:不正确的图像

标签: c++openmp

解决方案


推荐阅读