【问题标题】:OpenMP in C array reduction / parallelize the codeC 数组缩减/并行化代码中的 OpenMP
【发布时间】:2021-04-28 11:33:44
【问题描述】:

我的代码有问题,它应该打印一定数量的出现次数。

我想用 OpenMP 并行化这段代码,我尝试对数组使用归约,但它显然没有按我的意愿工作。

错误是:“分段错误”。一些变量应该是私有的吗?还是我尝试使用减少的方式有问题?

我认为每个线程都应该计算数组的一部分,然后以某种方式合并它。

#pragma omp parallel for reduction (+: reasult[:i])
    for (i = 0; i < M; i++) {   
      for(j = 0; j < N; j++) {
         if ( numbers[j] == i){
            result[i]++;
         }
      }
  }

N 是一个大数字,告诉我有多少个数字。 Numbers 是所有数字的数组和每个数字之和的结果数组。

【问题讨论】:

    标签: arrays c multithreading parallel-processing openmp


    【解决方案1】:

    首先你的名字有错别字

    #pragma omp parallel for reduction (+: reasult[:i])
    

    实际上应该是“结果”而不是“结果”

    尽管如此,你为什么要部分使用result[:i] 的数组?根据您的代码,您似乎想减少整个数组,即:

    #pragma omp parallel for reduction (+: result)
        for (i = 0; i < M; i++)   
          for(j = 0; j < N; j++)
             if ( numbers[j] == i)
                result[i]++;
    

    当编译器不支持OpenMP 4.5 数组缩减功能时,可以选择显式实现缩减 (check this SO thread to see how)。

    正如 @Hristo Iliev 在 cmets 中指出的那样:

    假设 M * sizeof(result[0]) / #threads 是 缓存行大小,即使 M 的值很大时不是 够了,完全没有必要减少 过程。除非程序在 NUMA 系统上运行,否则就是这样。

    假设满足上述条件,如果仔细分析最外层循环迭代(ie,变量i)分配给线程,并且由于使用变量i要访问result 数组,每个线程将更新result 数组的不同位置。因此,您可以将代码简化为:

    #pragma omp parallel for
    for (i = 0; i < M; i++)   
       for(j = 0; j < N; j++)
          if ( numbers[j] == i)
             result[i]++;
    

    【讨论】:

    • 前提是M * sizeof(result[0]) / #threads是cache line size的倍数,即使不是M的值足够大,也绝对没有必要涉及减少过程。除非程序在 NUMA 系统上运行,否则就是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多