C ++

如何安全地将嵌套的for-loop线程化,以便在具有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.;
                }
            }
        }
    }

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

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

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

  • 工作共享区域可能没有紧密嵌套在工作共享,显式任务,关键,有序或主域中。
  • 障碍区域可能没有紧密嵌套在工作共享,显式任务,关键,有序或主区域内。
  • MASTER区域可能没有紧密嵌套在工作共享或显式TASK区域内。
  • ORDERED区域可能没有紧密嵌套在CRITICAL或显式任务区域内。
  • ORDERED区域必须用ORDERED子句紧密嵌套在循环区域(或并行循环区域)内。
  • CRITICAL区域可能不会嵌套(紧密或以其他方式)在具有相同名称的CRITICAL区域内(尽管违反此限制的报告是与此不同的错误类型)。
  • 在SO之前已经提出并回答了类似的问题。

    OpenMP,for循环内部分

    OpenMP for master区域:“主区域可能没有紧密嵌套在工作共享或显式任务区域内”

    链接地址: http://www.djcxy.com/p/79237.html

    上一篇: c++

    下一篇: Openmp: nested loops and allocation