C 多维嵌套OpenMP循环
在OpenMP中,并行化多维并行循环的正确方法是什么?在编译时,维度的数量是已知的,但哪些维度会很大则不知道。他们中的任何一个都可能是一个、两个或一百万。我当然不希望N维循环使用NC 多维嵌套OpenMP循环,c,parallel-processing,openmp,nested-loops,C,Parallel Processing,Openmp,Nested Loops,在OpenMP中,并行化多维并行循环的正确方法是什么?在编译时,维度的数量是已知的,但哪些维度会很大则不知道。他们中的任何一个都可能是一个、两个或一百万。我当然不希望N维循环使用Nomp并行 想法: 这个问题在概念上很简单。只有最外层的“大”循环需要并行化,但循环维度在编译时是未知的,可能会发生变化 动态设置omp\u set\u num\u threads(1)和\pragma omp for schedule(静态、大量)是否会使某些循环并行化成为不可行的?这会产生不希望的副作用/开销吗?
omp并行
想法:
- 这个问题在概念上很简单。只有最外层的“大”循环需要并行化,但循环维度在编译时是未知的,可能会发生变化
- 动态设置
和omp\u set\u num\u threads(1)
是否会使某些循环并行化成为不可行的?这会产生不希望的副作用/开销吗?感觉像是一堆乱七八糟的东西\pragma omp for schedule(静态、大量)
- (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>
}
...
}
}
for(i0=0;i0如前所述,collapse
指令可能就是您正在寻找的。这将基本上形成一个单独的循环,然后对其进行并行化,并专为此类情况而设计。因此,您应该:
#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>
}
...
}
}
用于折叠的pragma omp并行(N)
对于(int i0=0;i0+1对于一个精心呈现的问题,获得正确的答案就是提出正确的问题。‘当然,参考规范也没什么坏处。:)谢谢!当当,这很简单。我看到了,以为因为某种原因它不起作用,然后就忘了。是的。看起来很对。而且看起来像是用#omp parallel{#omp for collapse{#omp parallel{#omp for collapse{…}嵌套它
是有效的。这并不是一个好主意,但它适用于大型数据集上的函数评估,因此f(g(x))应该是完全有效的。无论如何,谢谢!但是要注意两件事。第一,collapse子句仅在OpenMP V3.0及以上版本中存在。第二,虽然在使用collapse子句时不必特别将循环迭代变量设为私有,但如果删除了collapse子句,则最好按上述方式声明它们(使用C99语法)或将它们放在private子句中。否则它们将被共享,您将遇到问题。使用实现3.0的gcc 4.4.4。感谢提醒我检查。我喜欢#pragma omp parallel default(无)
,这样你就不会粗心了。另外,仅供参考,索引不能是数组元素,即int i[N]
。编译器错误。