如何使用 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/