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。 术语“紧密嵌套的区域”是指动态嵌套在另一个区域内的区域,在它们之间没有嵌套平行区域。
在SO之前已经提出并回答了类似的问题。
OpenMP,for循环内部分
OpenMP for master区域:“主区域可能没有紧密嵌套在工作共享或显式任务区域内”
链接地址: http://www.djcxy.com/p/79237.html上一篇: c++