【发布时间】:2018-01-27 11:03:56
【问题描述】:
我有一个由nxn 元素组成的二维网格。在一次迭代中,我通过平均其邻居的值来计算一个元素的值。那就是:
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
grid[i][j] = (grid[i-1][j] + grid[i][j-1] + grid[i+1][j] + grid[i][j+1])/4.0;
我需要为iter 的迭代次数运行上述嵌套循环。
我需要的是以下内容:
- 我需要线程来计算这个平均值,等到所有线程都完成计算,然后一次性更新网格。
- 具有
iter迭代的循环将按顺序运行,但在每次迭代期间,每个i和j的grid[i][j]值应并行计算。
为此,我有以下想法和问题:
- 也许使网格 共享 并通过仅将这 4 个元素 私有 复制到线。 (基本上网格由所有线程共享,但每个线程中也有 4 个 iteration-specific 元素的本地副本。)这可能吗?强>
- 实际上是否需要
barrier才能让所有线程完成并开始下一次迭代?
我对 OpenMP 的思维方式非常陌生,我完全迷失在这个简单的问题中。如果有人能帮助解决我的困惑,我将不胜感激。
【问题讨论】:
-
当前您正在根据同一数组的邻居计算平均值,并立即将其写入当前数组元素。顺便说一句,这看起来很可疑,因为 depedenices。一旦你去并行线程,你将不得不做一个非常复杂的同步方案,让正确的线程等待其他线程的结果。即网格 [2][2] 的计算更新必须等到 [1][1]、[3,2] 和所有其他邻居的计算完成。和其他应该等待 gheir 邻居,...否则你将有未定义的行为。这是你想要的吗?
-
您应该能够找到有关 jacobi 迭代并行性的有用讨论。它可能会超出临界范围。
-
一种简单的方法是将所有工作保存到第二个网格中。当你的计算全部完成后,你可以交换网格和网格2。
-
低效怎么办?记忆?您需要 2 个副本,无论如何您都需要。它可以是 OpenMP 友好的,如果处理得当(交换指针),后循环更新会非常快。
-
@complextea 在您的示例中它不能像这样工作。您使用以前在其他迭代中计算的平均值。您需要第二个数组来保存结果。在这种情况下,您可以在每次迭代中使用线程,而无需同步(“join”除外)。这很可能是矫枉过正。您只需要定义其中的几个,即 8 并重用。
标签: c++ multithreading openmp barrier