2015-11-19 124 views
1

我正在試圖學習OpenMP,瞭解我正在編寫的程序。對於它的一部分,我試圖實現一個函數來查找大型數組的平均值。這裏是我的代碼:OpenMP平均值數組

double mean(double* mean_array){ 
    double mean = 0; 

    omp_set_num_threads(4); 
    #pragma omp parallel for reduction(+:mean) 



    for (int i=0; i<aSize; i++){ 
     mean = mean + mean_array[i]; 

    } 

    printf("hello %d\n", omp_get_thread_num()); 



    mean = mean/aSize; 

    return mean; 

} 

但是,如果我運行代碼它比順序版本運行速度慢。同樣對於我得到的打印聲明:

hello 0 
hello 0 

這對我沒有多大意義,不應該有4個hellos?

任何幫助,將不勝感激。

+0

在你發佈的代碼中沒有任何「hello」,所以目前還不清楚應該有多少。無論如何,什麼是'aSize'?如果它很小,那麼它並不奇怪,它是緩慢的;與啓動線程相關的開銷,並且除非您有足夠的數據來提高使用OpenMP的速度,否則開銷將佔據主導地位。 –

+0

嗨,對不起,我意外刪除了打印行,我更新了我的代碼並將其放回。aSize是2000000,所以我認爲這應該足夠大。 – user2320239

+0

對於剛剛添加的行,您應該只能得到一個'hello'。它是'for'循環之後的,這是你並行化的唯一東西,所以它只能由'0'線程運行。然而,它看起來是你打電話給你的功能兩次,所以它打印出來兩次。 –

回答

2

首先,你看不到4個「你好」的原因是因爲並行執行的程序的唯一部分是被包含在#pragma omp parallel內的所謂的並行區域。在你的代碼中是循環體(因爲omp parallel指令附加到for語句中),printf在程序的順序部分。

重寫代碼如下會做的伎倆:

#pragma omp parallel num_threads(4) 
{ 
    #pragma omp for reduction(+:mean) 
    for (int i=0; i<aSize; i++) { 
    mean = mean + mean_array[i]; 
    } 
    printf("hello %d\n", omp_get_thread_num()); 
} 

其次,你的程序運行速度比串行版本慢的事實,它可以取決於多種因素。首先,您需要確保數組足夠大,以便創建這些線程的開銷(通常在創建並行區域時發生)可以忽略不計。此外,對於小型陣列,您可能會遇到「緩存錯誤共享」問題,其中線程正在競爭同一緩存行,從而導致性能下降。