如何保证与OpenMP的数据同步?
How to ensure data synchronization with 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];
}
}
问题来自竞争条件,这是由于循环携带的依赖性。由于循环迭代 matriz
read/write 当前行和上一行,因此无法并行化包含循环(也不是内部循环)。列也是如此。
请注意,OpenMP 不会检查循环是否可以并行化(事实上,理论上通常不能)。 你有责任检查一下。此外,请注意,在整个迭代中使用临界区会序列化执行,从而破坏并行循环的目的(事实上,由于临界区的开销,它会变慢)。另请注意 #pragma omp critical
仅适用于下一条语句。保护行 matriz[i][0] = matriz[i-1][0];
不足以避免竞争条件。
我不认为当前代码可以(有效地)并行化。也就是说,如果您的目标是实现 1D/2D 模板,那么您可以使用双缓冲技术(即写入不同于输入数组的 2D 数组)。类似的逻辑可以应用于重复多次的 1D 模板(这显然是你想要做的)。请注意,在这种情况下,结果会有所不同。对于 1D 模板情况,这种双缓冲策略可以解决依赖性问题并使您能够并行化 inner-loop。对于 2D 模板情况,两个嵌套循环可以并行化。
当我尝试根据以下代码执行数学表达式时,矩阵值不一致,我该如何解决?
#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];
}
}
问题来自竞争条件,这是由于循环携带的依赖性。由于循环迭代 matriz
read/write 当前行和上一行,因此无法并行化包含循环(也不是内部循环)。列也是如此。
请注意,OpenMP 不会检查循环是否可以并行化(事实上,理论上通常不能)。 你有责任检查一下。此外,请注意,在整个迭代中使用临界区会序列化执行,从而破坏并行循环的目的(事实上,由于临界区的开销,它会变慢)。另请注意 #pragma omp critical
仅适用于下一条语句。保护行 matriz[i][0] = matriz[i-1][0];
不足以避免竞争条件。
我不认为当前代码可以(有效地)并行化。也就是说,如果您的目标是实现 1D/2D 模板,那么您可以使用双缓冲技术(即写入不同于输入数组的 2D 数组)。类似的逻辑可以应用于重复多次的 1D 模板(这显然是你想要做的)。请注意,在这种情况下,结果会有所不同。对于 1D 模板情况,这种双缓冲策略可以解决依赖性问题并使您能够并行化 inner-loop。对于 2D 模板情况,两个嵌套循环可以并行化。