我正在尝试为我正在编写的程序学习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/

10-13 06:10