gpt4 book ai didi

c++ - OpenMP parallel for inside do-while

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:16:46 27 4
gpt4 key购买 nike

我在尝试重构基于 OpenMP 的程序时遇到了一个可怕的可扩展性问题。以下(显然意义不大)OpenMP 程序似乎重现了该问题。当然,微小的示例代码可以重写为嵌套的 for 循环,并使用 collapse(2) 可以实现近乎完美的可扩展性。但是,我正在处理的原始程序不允许这样做。

因此,我正在寻找一种修复方法,以保持 do-while 结构。根据我的理解,OpenMP 应该足够智能以在迭代之间保持线程处于事件状态,并且我期望良好的可扩展性。为什么不是这样?

int main() {
const int N = 6000;
const int MAX_ITER = 2000000;
double max = DBL_MIN;

int iter = 0;
do {
#pragma omp parallel for reduction(max:max) schedule(static)
for(int i = 1; i < N; ++i) {
max = MAX(max, 3.3*i);
}
++iter;
} while(iter < MAX_ITER);

printf("max=%f\n", max);
}

我使用 Cray 编译器版本 8.3.4 测量了以下运行时间。

OMP_NUM_THREADS=1 : 0m21.535s
OMP_NUM_THREADS=2 : 0m12.191s
OMP_NUM_THREADS=4 : 0m9.610s
OMP_NUM_THREADS=8 : 0m9.767s
OMP_NUM_THREADS=16: 0m13.571s

这似乎类似于this question .提前致谢。感谢帮助! :)

最佳答案

你可以这样做:

#include <stdio.h>
#include <float.h>
#include <omp.h>
#define MAX( a, b ) ((a)>(b))?(a):(b)

int main() {
const int N = 6000;
const int MAX_ITER = 2000000;
double max = DBL_MIN;

#pragma omp parallel reduction( max : max )
{
int iter = 0;
int nbth = omp_get_num_threads();
int tid = omp_get_thread_num();
int myMaxIter = MAX_ITER / nbth;
if ( tid < MAX_ITER % nbth ) myMaxIter++;
int chunk = N / nbth;
do {
#pragma omp for schedule(dynamic,chunk) nowait
for(int i = 1; i < N; ++i) {
max = MAX(max, 3.3*i);
}
++iter;
} while(iter < myMaxIter);
}
printf("max=%f\n", max);
}

我很确定可扩展性应该得到显着改善。

注意:由于我意识到外循环(do-while)的迭代次数对于不同的线程可能不同,所以我不得不多次回到这个问题上,调度是至关重要的omp for 循环的一部分不是静态的,否则,在最后一次迭代时可能会出现死锁。我做了一些测试,我认为所提出的解决方案既安全又有效。

关于c++ - OpenMP parallel for inside do-while,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32595934/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com