【发布时间】:2011-06-08 15:36:44
【问题描述】:
我编写了简单的 C++ 代码来计算数组归约和,但使用 OpenMP 归约程序运行缓慢。程序有两种变体:一种是最简单的求和,另一种是复杂数学函数的求和。在代码中对复杂的变体进行了注释。
#include <iostream>
#include <omp.h>
#include <math.h>
using namespace std;
#define N 100000000
#define NUM_THREADS 4
int main() {
int *arr = new int[N];
for (int i = 0; i < N; i++) {
arr[i] = i;
}
omp_set_num_threads(NUM_THREADS);
cout << NUM_THREADS << endl;
clock_t start = clock();
int sum = 0;
#pragma omp parallel for reduction(+:sum)
for (int i = 0; i < N; i++) {
// sum += sqrt(sqrt(arr[i] * arr[i])); // complex variant
sum += arr[i]; // simple variant
}
double diff = ( clock() - start ) / (double)CLOCKS_PER_SEC;
cout << "Time " << diff << "s" << endl;
cout << sum << endl;
delete[] arr;
return 0;
}
我是通过ICPC和GCC编译的:
icpc reduction.cpp -openmp -o reduction -O3
g++ reduction.cpp -fopenmp -o reduction -O3
处理器:Intel Core 2 Duo T5850,操作系统:Ubuntu 10.10
有简单和复杂变体的执行时间,使用和不使用 OpenMP 编译。
简单变体“sum += arr[i];”:
icpc
0.1s without OpenMP
0.18s with OpenMP
g++
0.11c without OpenMP
0.17c with OpenMP
复杂变体“sum += sqrt(sqrt(arr[i] * arr[i]));”:
icpc
2,92s without OpenMP
3,37s with OpenMP
g++
47,97s without OpenMP
48,2s with OpenMP
在系统监视器中,我看到 2 个内核在使用 OpenMP 的程序中工作,而 1 个内核在没有 OpenMP 的程序中工作。我将在 OpenMP 中尝试多个线程并且没有加速。我不明白为什么还原很慢。
【问题讨论】:
-
对于简单版本,您将获得大约 2 倍的加速,并且您有 2 个内核!
-
对不起,我混淆了 OpenMP 和没有 OpenMP。但我的问题是正确的。