如何保证与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 模板情况,两个嵌套循环可以并行化。