【问题标题】:Multi-dimensional nested OpenMP loop多维嵌套 OpenMP 循环
【发布时间】:2011-03-13 03:59:49
【问题描述】:

在 OpenMP 中并行化多维令人尴尬的并行循环的正确方法是什么?维度的数量在编译时是已知的,但不知道哪些维度会很大。它们中的任何一个都可能是一、二或一百万。当然,我不希望 N 个 omp parallel 用于 N 维循环...

想法:

  • 这个问题在概念上很简单。只有最外面的“大”循环需要并行化,但循环尺寸在编译时是未知的,并且可能会发生变化。

  • 动态设置omp_set_num_threads(1)#pragma omp for schedule(static, huge_number) 是否会使某些循环并行化成为无操作?这会产生不良的副作用/开销吗?感觉像个杂种。

  • OpenMP Specification (2.10, A.38, A.39) 说明了符合和不符合嵌套并行性之间的区别,但并未提出解决此问题的最佳方法。

  • 重新排序循环是可能的,但可能会导致大量缓存未命中。展开是可能的,但不是微不足道的。还有其他方法吗?

这是我想要并行化的内容:

for(i0=0; i0<n[0]; i0++) {
  for(i1=0; i1<n[1]; i1++) {
    ...
       for(iN=0; iN<n[N]; iN++) {
         <embarrasingly parallel operations>
       }
    ...
  }
}

谢谢!

【问题讨论】:

  • +1 提出一个很好的问题
  • 获得正确答案就是提出正确的问题。 '当然,参考规范也没有什么坏处。 :)

标签: c parallel-processing openmp nested-loops


【解决方案1】:

collapse 指令可能是您正在寻找的,如here 所述。这将基本上形成一个循环,然后将其并行化,并且专为此类情况而设计。所以你会这样做:

#pragma omp parallel for collapse(N)
for(int i0=0; i0<n[0]; i0++) {
  for(int i1=0; i1<n[1]; i1++) {
    ...
       for(int iN=0; iN<n[N]; iN++) {
         <embarrasingly parallel operations>
       }
    ...
  }
}

一切就绪。

【讨论】:

  • 谢谢!唐,这很容易。我看到了,以为由于某种原因它不起作用,然后忘记了。是的。看起来刚刚好。看起来用#omp parallel{ #omp for collapse{ #omp parallel{ #omp for collapse{ ... } } } } 嵌套它是有效的。并不是说这是一个好主意,而是用于对大型数据集进行函数评估,因此 f(g(x)) 应该是完全有效的。无论如何,谢谢!
  • 有两点需要注意。首先,collapse 子句只存在于 OpenMP V3.0 及以上版本中。其次,虽然您不必在使用折叠子句时专门将循环迭代变量设为私有,但如果您删除了折叠子句,那么您最好按照上述方式声明它们(使用 C99 语法)或将它们放在私有子句中.否则它们将被共享,您将遇到问题。
  • 使用实现 3.0 的 gcc 4.4.4。谢谢你提醒我检查。我喜欢#pragma omp parallel default(none),这样你就不会粗心。另外仅供参考,结果索引不能是数组元素,即int i[N]。编译器错误。
猜你喜欢
  • 1970-01-01
  • 2016-07-27
  • 1970-01-01
  • 2012-11-14
  • 2012-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
相关资源
最近更新 更多