gpt4 book ai didi

c - 在这种情况下,您将如何避免错误共享?

转载 作者:行者123 更新时间:2023-11-30 15:44:44 25 4
gpt4 key购买 nike

在下面的代码中,我使用 OpenMP 的标准 parallel for 子句进行并行化。

#pragma omp parallel for private(i, j, k, d_equ) shared(cells, tmp_cells, params)
for(i=0; i<some_large_value; i++)
{
for(j=0; j<some_large_value; j++)
{
....
// Some operations performed over here which are using private variables
....

// Accessing a shared array is causing False Sharing
for(k=0; k<10; k++)
{
cells[i * width + j].speeds[k] = some_calculation(i, j, k, cells);
}
}
}

这使我的运行时间得到了显着改善(~140 秒到~40 秒),但我仍然注意到一个区域确实落后了 - 我在上面标记的最内层循环。

我确信上面的数组会导致错误共享,因为如果我进行下面的更改,我会看到性能的另一个巨大飞跃(~40 秒到~13 秒)。

 for(k=0; k<10; k++)
{
double somevalue = some_calculation(i, j);
}

换句话说,一旦我将内存位置更改为写入私有(private)变量,速度就有了巨大的提高。

有什么方法可以通过避免我刚才解释的场景中的错误共享来改善运行时间?尽管问题本身被多次提及,但我似乎无法在网上找到许多似乎有助于解决此问题的资源。

我有一个想法,创建一个过大的数组(所需数组的 10 倍),以便在每个元素之间保留足够的边距空间,以确保当它进入缓存行时,没有其他线程会拾取它。然而这并没有达到预期的效果。

是否有任何简单(甚至困难,如果需要)的方法来减少或消除该循环中发现的错误共享?

任何形式的见解或帮助将不胜感激!

编辑:假设 some_calculation() 执行以下操作:

 (tmp_cells[ii*params.nx + jj].speeds[kk] + params.omega * (d_equ[kk] - tmp_cells[ii*params.nx + jj].speeds[kk]));

我无法将此计算移出 for 循环,因为我依赖于每次迭代计算的 d_equ。

最佳答案

在回答你的问题之前,我必须问一下,当你使用整个单元格作为函数some_calcutation()的输入时,这真的是错误共享情况吗?看来您实际上正在共享整个数组。您可能想提供有关此功能的更多信息。

如果是,请继续执行以下操作。

您已经证明私有(private)变量double somevalue将提高性能。为什么不直接使用这种方法呢?

您可以在 for k 循环之前定义一个私有(private)数组 private_speed[10],而不是使用单个 double 变量,计算它们在循环中,并在循环后将其复制回 cells ,类似于

 memcpy(cells[i*width+j].speed, private_speed, sizeof(...));

关于c - 在这种情况下,您将如何避免错误共享?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19348500/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com