Mac*_*ram 0 c parallel-processing openmp
当我尝试从以下代码中执行数学表达式时,矩阵值不一致,如何解决这个问题?
#pragma omp parallel num_threads (NUM_THREADS)
{
#pragma omp for
for(int i = 1; i < qtdPassos; i++)
{
#pragma omp critical
matriz[i][0] = matriz[i-1][0]; /
for (int j = 1; j < qtdElementos-1; j++)
{
matriz[i][j] = (matriz[i-1][j-1] + (2 * matriz[i-1][j]) + matriz[i-1][j+1]) / 4; // Xi(t+1) = [Xi-1 ^ (t) + 2 * Xi ^ (t)+ Xi+1 ^ (t)] / 4
}
matriz[i][qtdElementos-1] = matriz[i-1][qtdElementos-1];
}
}
Run Code Online (Sandbox Code Playgroud)
问题来自于循环携带依赖性引起的竞争条件。由于循环迭代读取/写入当前行和上一行,因此包围循环(内部循环也不能)无法并行化。这同样适用于列。matriz
请注意,OpenMP 不会检查循环是否可以并行化(事实上,理论上一般不能并行化)。您有责任检查这一点。另外,请注意,在整个迭代中使用关键部分会使执行串行化,从而违背了并行循环的目的(事实上,由于关键部分的开销,它会变慢)。另请注意,这只#pragma omp critical适用于下一条语句。保护线路matriz[i][0] = matriz[i-1][0];不足以避免竞争状况。
我不认为当前的代码可以(有效地)并行化。话虽这么说,如果您的目标是实现 1D/2D 模板,那么您可以使用双缓冲技术(即写入与输入数组不同的 2D 数组)。类似的逻辑可以应用于重复多次的一维模板(这显然是您想要做的)。请注意,在这种情况下,结果会有所不同。对于一维模板情况,这种双缓冲策略可以解决依赖性问题并使您能够并行化内循环。对于 2D 模板情况,两个嵌套循环可以并行化。