2011-06-08 70 views
1

我編寫簡單的C++代碼來計算數組減少總和,但OpenMP減少程序的運行速度很慢。程序有兩種變體:一種是最簡單的和,另一種是複雜數學函數的和。在代碼中複雜的變體被評論。OpenMP緩慢減少

icpc reduction.cpp -openmp -o reduction -O3 
g++ reduction.cpp -fopenmp -o reduction -O3 

處理器::英特爾酷睿2 T5850,OS:

#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編譯它的Ubuntu 10.10

有很多簡單和複雜的變體,與編譯的執行時間沒有OpenMP。

簡單變體 「之和+ = ARR [I];」:

icpc 
0.1s without OpenMP 
0.18s with OpenMP 

g++ 
0.11c without OpenMP 
0.17c with OpenMP 

複雜變體「之和+ = SQRT(SQRT(ARR [I] *的常用3 [1])); 「:

icpc 
2,92s without OpenMP 
3,37s with OpenMP 

g++ 
47,97s without OpenMP 
48,2s with OpenMP 

在系統監視器中,我看到2個內核在OpenMP程序中工作,1個內核在沒有OpenMP的程序中工作。我會在OpenMP中嘗試幾個線程,並且不加速。我不明白爲什麼減速很慢。

+1

對於簡單的版本,你得到約2倍的加速,並且你有2個核心! – 2011-06-08 16:04:10

+0

對不起,我混淆了和沒有OpenMP。但我的問題是正確的。 – 2011-06-08 16:12:46

回答

4

函數clock()用於測量整個進程消耗的處理器時間,因此打印時間顯示所有線程使用的時間總和。如果您想查看牆面時間(實際從開始到結束時間),請使用times()在POSIX系統上的功能

+2

一個問題是您正在使用clock()來測量時間。 clock的手冊頁顯示「clock()函數返回程序使用的處理器時間的近似值」。並行運行的處理器時間通常會大於串行運行時間。你想測量掛鐘時間。 OpenMP提供了一個功能來執行此操作。有關信息,請參閱OpenMP規範中的omp_get_wtime()。 – ejd 2011-06-08 16:26:27

+0

非常感謝!我嘗試omp_get_wtime()並顯示OpenMP程序運行得更快。現在我有32個線程的最大加速比。 – 2011-06-08 16:29:53

+0

@Mikhail:2核心機器上的32個線程?真?這沒什麼意義。你是計算綁定的還是內存綁定的,在你的代碼中,擁有比核心更多的線程並不會改善問題。所以我很驚訝。 – 2011-06-08 21:56:28

1

你在做什麼很簡單,你可能會受到內存帶寬的限制。除非從工作中獲取數據所需的時間,否則我很少會獲得任何加速。另外減少了在合併所有子結果方面的額外工作。