Openmp - 嵌套 for 循环

use*_*240 0 c++ parallel-processing multithreading for-loop 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.;
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

Ade*_*ler 5

您不能以这种方式嵌套 OMP 区域。来自OMP 文档(英特尔)

两个 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 区域内(尽管违反此限制会报告为与此不同的错误类型)。

类似的问题之前已经被问过并回答过。

OpenMP,for 循环内部部分

具有主区域的 OpenMP for 循环:“主区域可能不会紧密嵌套在工作共享或显式任务区域内”