c++ - 使用openmp优化内部循环依赖于外部循环的并行嵌套循环

标签 c++ c openmp

如何使用 openmp 对这段代码进行更好的优化。 线程数为 6,但无法获得更好的性能。

我尝试了不同的调度选项,但无法对其进行更好的优化。 有没有办法获得更好的结果?

int lenght = 40000;
int idx;
long *result = new long[ size ];

#pragma omp parallel for private(idx) schedule(dynamic)
for ( int i = 0; i < lenght; i++ ) {
    for ( int j = 0; j < i; j++  ) {
        idx = (int)( someCalculations( i, j ) );
        #pragma omp atomic
        result[ idx ] += 1;
    }
}

这段代码确实优化了计算时间,但我还是需要更好的结果。

提前致谢。

最佳答案

从 OpenMP 4.0 开始,您可以编写 own reduction .

想法是:

  • for 循环中,您告诉编译器减少您在每个循环中修改的地方。
  • 由于 omp 不知道如何减少这样的数组,您必须编写自己的加法器 my_add,它将简单地对两个数组求和。
  • 你告诉 omp 如何在你的 reducer 中使用它 (myred)

#include <stdio.h>
#include <stdlib.h>

#define LEN 40000

int someCalculations(int i, int j)
{
    return i * j % 40000  ;
}

/* simple adder, just sum x+y in y */
long *my_add(long * x, long *y)
{
    int i;
 #pragma omp parallel for private(i)
    for (i = 0; i < LEN; ++i)
    {
        x[i] += y[i];
    }

    free(y);
    return x;

}

/* reduction declaration:
   name
   type
   operation to be performed
   initializer */
#pragma omp declare reduction(myred: long*:omp_out=my_add(omp_out,omp_in))\
    initializer(omp_priv=calloc(LEN, sizeof(long)))

int main(void)
{
    int i, j;
    long *result = calloc(LEN, sizeof *result);

// tell omp how to use it
#pragma omp parallel for reduction(myred:result) private (i, j)
    for (i = 0; i < LEN; i++) {
        for (j = 0; j < i; j++) {
            int idx = someCalculations(i, j);
            result[idx] += 1;
        }
    }

    // simple display, I store it in a file and compare 
    // result files with/without openmp to be sure it's correct...
    for (i = 0; i < LEN; ++i) {
        printf("%ld\n",  result[i]);
    }

    return 0;
}

没有 -fopenmp:真实 0m3.727s

使用 -fopenmp:真实 0m0.835s

关于c++ - 使用openmp优化内部循环依赖于外部循环的并行嵌套循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56290391/

相关文章:

c++ - 在 C++ 中通过接口(interface)的最佳方式?

c - 如何在avro-c中使用数组作为map的值

c - 在 C 中弹出一个空链表

c++ - 减少 openmp 的奇怪结果

c++ - C++中是否有可变长度数组?

c++ - 使用opengl和c++使用动画(经过一段时间后一个一个地)翻译三角形

c++ - Eigen :设置 EIGEN_STACK_ALLOCATION_LIMIT 不起作用

c - 如何用等效的 strcat() 替换 memcpy() ?

c++ - 如何将 OpenMP 和 MPI 导入大型 CLion CMake 项目?

替换 openmp 关键区域的汇编指令