如何确保数据与OpenMP同步?

发布于 2025-01-25 07:43:03 字数 760 浏览 2 评论 0原文

当我尝试从以下代码中进行数学表达式时,矩阵值不一致,该如何解决?

#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]; 
        }
    }

When I try to do the math expression from the following code the matrix values are not consistent, how can I fix that?

#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]; 
        }
    }

Matrix execution

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不必你懂 2025-02-01 07:43:03

问题来自种族条件,这是由于循环依赖性引起的。由于循环迭代matriz读取/编写当前和上一行,因此无法并行循环(也不能平行循环)。列也适用。

请注意,OpenMP不检查循环是否可以并行化(实际上,从理论上讲,它通常不能)。检查一下是您的责任。此外,请注意,使用整个迭代的临界部分序列地将执行打败并行循环的目的(实际上,由于临界部分的开销,它将较慢)。还请注意,#pragma OMP关键仅适用于下一个语句。保护行matriz [i] [0] = matriz [i-1] [0];不足以避免比赛条件。

我认为此当前代码无法(有效)并行。话虽如此,如果您的目标是实现1D/2D模板,则可以使用双重缓冲技术(即,以与输入阵列不同的2D数组写入)。可以将类似的逻辑应用于1D模板多次重复(显然是您想做的)。请注意,在这种情况下,结果将有所不同。对于1D模板案例,这种双重缓冲策略可以解决依赖关系问题,并使您可以并行化内环。对于2D模板盒,两个嵌套环可以并行化。

The problem comes from a race condition which is due to a loop carried dependency. The encompassing loop cannot be parallelised (nor the inner loop) since loop iterations matriz read/write the current and previous row. The same applies for the column.

Note that OpenMP does not check if the loop can be parallelized (in fact, it theoretically cannot in general). It is your responsibility to check that. Additionally, note that using a critical section for the whole iteration serializes the execution defeating the purpose of a parallel loop (in fact, it will be slower due to the overhead of the critical section). Note also that #pragma omp critical only applies on the next statement. Protecting the line matriz[i][0] = matriz[i-1][0]; is not enough to avoid the race condition.

I do not think this current code can be (efficiently) parallelised. That being said, if your goal is to implement a 1D/2D stencil, then you can use a double buffering technique (ie. write in a 2D array that is different from the input array). A similar logic can be applied for 1D stencil repeated multiple times (which is apparently what you want to do). Note that the results will be different in that case. For the 1D stencil case, this double buffering strategy can fix the dependency issue and enable you to parallelize the inner-loop. For the 2D stencil case, the two nested loops can be parallelized.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文