OpenMP 可能无法直接并行化的代码

标签 c openmp

OpenMP 可能无法直接并行化的代码

致力于自动并行化器并寻找 OpenMP 可能无法直接并行化的基准(“直接并行化”的意思是:只需指定正确的 OpenMP 指令,即可创建并行可执行文件而不修改代码)。

正题,是否可以使用 OpenMP 并行化以下代码?

1.

double a[ARRAY_DIM], c[ARRAY_DIM];
  .
double ret;
ret = 0.;
for ( i = 0; i < ARRAY_DIM; i++ ) {
  c[i] = exp( ret );
  ret += a[i];
}
return ret;

2.

double a[ARRAY_DIM], c[ARRAY_DIM];
   .
double ret;
ret = 0.;
for ( i = 0; i < ARRAY_DIM; i++ ) {
  if ( a[i] > 0.01 ) {
    ret = c[i];
  }
}
return ret;

最佳答案

代码示例 1 可以使用 prefix sum solution 与 OpenMP 并行化。

对于代码示例 2,我在下面的代码中有两个解决方案,分别称为 foo1foo2。函数 foo1 更容易实现,但如果 a[i] > 0.01 经常为真,则效率可能会低得多。例如,如果它始终为 true,那么它必须在每次迭代中写入 ret 以便杀死并行化。对于函数 foo2 ,它只需按线程顺序写入,而不是每次迭代,并且由于迭代次数远大于线程数,因此效率更高。

#include <omp.h>
#include <stdio.h>
#define ARRAY_DIM 1000
double a[ARRAY_DIM], c[ARRAY_DIM];

double foo1() {
  double ret = 0;
  #pragma omp parallel for ordered schedule(static)
  for (int i = 0; i < ARRAY_DIM; i++) {
    if ( a[i] > 0.01 ) {
      #pragma omp ordered
      ret = c[i];
    }
  }
  return ret;
}

double foo2() {
  int k = -1;
  #pragma omp parallel
  {
    int k2 = -1;
    #pragma omp for schedule(static)
    for (int i = 0; i < ARRAY_DIM; i++) if ( a[i] > 0.01 ) k2 = i;
    #pragma omp for schedule(static) ordered
    for(int i=0; i<omp_get_num_threads(); i++)
      #pragma omp ordered
      if(k2 >= 0) k = k2;
  }
  return c[k];
}

int main(void) {
  for(int i=0; i<ARRAY_DIM; i++) a[i] = 1;
  for(int i=0; i<ARRAY_DIM; i++) c[i] = i;
  printf("%f\n", foo1());
  printf("%f\n", foo2());
}

关于OpenMP 可能无法直接并行化的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51595597/

相关文章:

rendering - 超线程……让我的渲染器慢了 10 倍

c - 获取 sscanf 读取的字符数?

floating-point - 具有浮点范围的 OpenMP 并行

c - 如何判断应用程序是否已经在运行? C 可移植 Linux/Win

c - 指令级的有符号数模数

c - OpenMP 和私有(private)可重用内存

c++ - 如何提高我的 OpenMP 代码的性能?

c - OpenMP Parallel for 循环显示性能提升很小

c - 传递指针或 const 结构是否有速度差异

c++ - C 和 C++ 中静态变量存储在哪里?