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)
您不能以这种方式嵌套 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 循环:“主区域可能不会紧密嵌套在工作共享或显式任务区域内”