【问题标题】:Is this the correct use of OpenMP firstprivate?这是 OpenMP firstprivate 的正确使用吗?
【发布时间】:2020-09-28 20:30:13
【问题描述】:

我需要并行化以下内容:

for(i=0; i<n/2; i++)
   a[i] = a[i+1] + a[2*i]

并行时,输出将不同于顺序输出,因为“读取”值将被“重写”。为了获得顺序输出,然后并行化,我想使用 firstprivate(a)。因为 firstprivate 给每条踏步一个副本。

假设有 4 个线程和一个 100 个循环。

  • 1 --> i = 0 到 24
  • 2 --> i = 25 到 49
  • 3 --> i = 50 到 74
  • 4 --> i =75 到 99

这意味着每个踏板将重写 25% 的数组。

当并行区域结束时,所有线程“合并”。这是否意味着您得到的 a 与按顺序运行它一样?

#pragma omp parallel for firstprivate(a)
for(i=0; i<n/2; i++)
   a[i] = a[i+1] + a[2*i]

问题:

  • 我的思维方式正确吗?
  • 代码是否以正确的方式并行化以获得顺序输出?

【问题讨论】:

  • a 是什么类型? (此信息对于正确回答您的问题至关重要)。
  • @Zulan 感谢您的努力。它是用整数填充的 C 中的数组?这些信息是否足够?
  • 所以具体是int a[100]?因为这与 int* a 的处理方式不同。
  • 是的,int a[100];。我应该将其包含在代码示例中。我通过制作数组 a 的副本 b 并使用 b 来“读取”并让“重写”发生在 a 中来“修复”它。但在我看来,这不是一个巧妙的解决方案。

标签: c++ c parallel-processing openmp


【解决方案1】:

如您所述,使用firstprivate 复制每个线程的数据并不能真正帮助您取回数据。

事实上,最简单的解决方案是将输入和输出分开并共享(默认)。

为了避免复制,最好只在代码中使用新变量而不是 b。或者,您可以只使用指针并交换它们。

int out[100];
#pragma omp parallel for
for(i=0; i<n/2; i++)
   out[i] = a[i+1] + a[2*i]

// use out from here when you would have used a.

没有简单而通用的方法来为每个线程拥有a 的私​​有副本,然后将它们合并。 lastprivate 只是从执行最后一次迭代的线程复制一个不完整 输出数组,reduction 不知道从哪个数组中获取哪些元素。即使是这样,为每个线程复制整个数组也是一种浪费。在这里共享输入/输出效率更高。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-12
    • 2018-08-13
    • 2015-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 2012-05-11
    相关资源
    最近更新 更多