Openmp - 嵌套for循环

时间:2014-02-21 19:12:24

标签: c++ multithreading for-loop parallel-processing openmp

如何安全地在下面安装嵌套的for循环,以便在具有8个线程的核心上并行运行程序,并仍以正确的顺序输出数据。我尝试使用 #pragma omp for 命令,但这会给我一条错误消息: 工作共享区域可能没有紧密嵌套在工作中 - 共享,关键或显式任务区域

注意:此代码用于介绍并行编程,因此为了优化而编写的代码很差

#pragma omp parallel private(t, i, j) shared(nx, ny, nt)
{
    // main loop

    for (int t = 0; t < nt; t++)
    {
        cout << "\n" << t;
        cout.flush();

        // first block 

        for (int i = 0; i < nx; i++)
        {
            for(int j=0; j < ny ;j++)
            {
                if (i> 0 && i < nx - 1 && j >0 && j < ny - 1) 
                {
                    vr[i][j] = (vi[i+1][j]+vi[i-1][j]+vi[i][j-1]+vi[i][j+1]) / 4.;
                } 
                else if (i == 0 && i < nx - 1 && j > 0 && j < ny - 1) 
                {
                    vr[i][j] = (vi[i+1][j]+10.+vi[i][j-1]+vi[i][j+1]) / 4.;
                } 
                else if (i > 0 && i == nx - 1 && j > 0 && j < ny - 1) 
                {
                    vr[i][j] = (5.+vi[i-1][j]+vi[i][j-1]+vi[i][j+1]) / 4.;
                } 
                else if (i > 0 && i < nx - 1 && j == 0 && j < ny - 1) 
                {
                    vr[i][j] = (vi[i+1][j]+vi[i-1][j]+15.45+vi[i][j+1]) / 4.;
                } 
                else if (i > 0 && i < nx - 1 && j > 0 && j == ny - 1) 
                {
                    vr[i][j] = (vi[i+1][j]+vi[i-1][j]+vi[i][j-1]-6.7) / 4.;
                }
            }
        }

        // second block

        for (int i = 0; i < nx; i++) 
        {
            for (int j = 0; j < ny; j++)
            {
                if (fabs(fabs(vr[i][j]) - fabs(vi[i][j])) < 1e-2) 
                {
                    fout << "\n" << t << " " << i << " " << j << " "
                         << fabs(vi[i][j]) << " " << fabs(vr[i][j]);
                }
            }

            #pragma omp for schedule(static,100)

            // third block

            for (int i = 0; i < nx; i++) 
            {
                for (int j = 0; j < ny; j++) 
                {
                    vi[i][j] = vi[i][j] / 2. + vr[i][j] / 2.;
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:2)

您无法以这种方式嵌套OMP区域。来自OMP documentation (Intel)

  

两个OpenMP构造是不正确(动态)嵌套的。   OpenMP规范对如何动态嵌套OpenMP构造施加了若干限制,也就是说,在执行另一个区域期间可以合法地遇到哪些OpenMP构造。 OpenMP并行区域可以相互嵌套,但有一些限制。 一般来说,如果存在由SINGLE,CRITICAL或MASTER指令创建的中间单线程区域,则只能嵌套两个并行区域。

     

准确地说,以下限制适用。在下文中,术语“工作共享区域”是以下任何一种构造的简写:循环(FOR / DO),SECTIONS,SINGLE或WORKSHARE。术语“紧密嵌套的区域”是指动态嵌套在另一个区域内的区域,它们之间没有嵌套的平行区域。

     
      
  • 工作共享区域可能不会紧密嵌套在工作共享,显式TASK,CRITICAL,ORDERED或MASTER区域内。
  •   
  • BARRIER区域可能不会紧密嵌套在工作共享,显式TASK,CRITICAL,ORDERED或MASTER区域内。
  •   
  • MASTER区域可能不会紧密嵌套在工作共享或显式TASK区域内。
  •   
  • ORDERED区域可能不会紧密嵌套在CRITICAL或显式TASK区域内。
  •   
  • ORDERED区域必须使用ORDERED子句紧密嵌套在循环区域(或并行循环区域)内。
  •   
  • CRITICAL区域不能嵌套(密切地或以其他方式)在具有相同名称的CRITICAL区域内(尽管违反此限制的报告的错误类型与此不同)。
  •   

之前在SO上已经提出并回答了类似的问题。

OpenMP, for loop inside section

OpenMP for loop with master region: "master region may not be closely nested inside of work-sharing or explicit task region"