多维嵌套的OpenMP循环

问题描述:

在OpenMP中并行化多维尴尬平行循环的正确方法是什么?尺寸的数量在编译时是已知的,但哪些尺寸很大并不是。他们中的任何一个可能是一个,两个或一百万。当然我不想ňomp parallel的为N维环...多维嵌套的OpenMP循环

思考:

  • 问题的概念很简单。只有最外面的'大'循环需要并行化,但循环维度在编译时是未知的,并且可能会改变。

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

  • 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> 
     } 
    ... 
    } 
} 

谢谢!

+0

+1对于一个出色的问题 – pmg 2011-03-13 12:38:10

+1

获得正确的答案就是提出正确的问题。 '当然,参考规范也没有什么坏处。 :) – Ricky 2011-03-13 16:48:58

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> 
     } 
    ... 
    } 
} 

并且都设置好了。

+0

谢谢!当然,那很容易。我看到了,认为它不能出于某种原因,然后忘了它。对。看起来是正确的。看起来像嵌套#omp parallel {#omp for collapse {#omp parallel {#omp for collapse {...}}}}是有效的。这不是一个好主意,但它是用于大数据集上的函数评估,因此f(g(x))应该是完全有效的。不管怎样,谢谢! – Ricky 2011-03-13 13:40:26

+2

两件事要注意。首先,崩溃子句仅在OpenMP V3.0及更高版本中提供。其次,虽然在使用collapse子句时不必专门将循环迭代变量设置为private,但如果删除了collapse子句,则最好将它们声明为上面的形式(使用C99语法),或者将它们放在私有子句中。否则,他们会被分享,你会有问题。 – ejd 2011-03-13 17:19:53

+1

使用实现3.0的gcc 4.4.4。谢谢你提醒我检查。我喜欢'#pragma omp parallel default(none)',只是为了避免疏忽。此外,FYI指出索引不能是数组元素,即'int i [N]'。编译器错误。 – Ricky 2011-03-13 17:32:47