我正在尝试为我正在编写的程序学习OpenMP。其中一部分,我试图实现一个函数来求一个大数组的平均值。这是我的代码:
double mean(double* mean_array){
double mean = 0;
omp_set_num_threads( 4 );
#pragma omp parallel for reduction(+:mean)
for (int i=0; i<aSize; i++){
mean = mean + mean_array[i];
}
printf("hello %d\n", omp_get_thread_num());
mean = mean/aSize;
return mean;
}
但是,如果我运行代码,它的运行速度会比顺序版本慢。对于打印语句,我还得到:
hello 0
hello 0
这对我来说没什么意义,不是应该有4个地狱吗?
任何帮助都将不胜感激。
最佳答案
首先,您没有看到4个“hello”的原因是,程序中唯一并行执行的部分是#pragma omp parallel
中包含的所谓并行区域。在作为循环体的代码(因为omp parallel指令附加到for语句)中,printf
位于程序的顺序部分。
按如下方式重写代码可以做到这一点:
#pragma omp parallel num_threads(4)
{
#pragma omp for reduction(+:mean)
for (int i=0; i<aSize; i++) {
mean = mean + mean_array[i];
}
printf("hello %d\n", omp_get_thread_num());
}
其次,程序运行速度比顺序版本慢,这取决于多个因素。首先,需要确保数组足够大,以便创建这些线程(通常在创建并行区域时发生)的开销可以忽略不计。此外,对于小型阵列,您可能会遇到“缓存假共享”问题,其中线程正在争夺同一缓存线,从而导致性能下降。
关于c - 阵列的OpenMP平均值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33811991/