2013-11-03 37 views
2

我正在努力調整程序以使用OpenMP。我有一組嵌套for循環。最外面的for循環是沿着圖像的y軸循環。我想在循環中運行多個並行線程,但我很難快速完成。OpenMP For - 用於高速緩存優化的組循環

目前,當我運行8個線程運行,如:

thread 0 -> row 0,8,16... 
thread 1 -> row 1,9,17... 
thread 2 -> row 2,10,18... 
thread 3 -> row 3,11,19... 

我想它在塊運行,使線程0確實行的第一1/8。做這個的最好方式是什麼?

當前代碼:

... 
int y_percent = data_size_Y/8; 
int thread = 0; 

#pragma omp parallel for num_threads(8) firstprivate(vecs, bufferedOut,data_size_X, data_size_Y, kern_cent_X, kern_cent_Y, sum) 
for(int y = y_percent*omp_get_thread_num(); y < (omp_get_thread_num()+1)*y_percent; y++){ // the y coordinate of theoutput location we're focusing on  

回答

5

可以使用pragma語句中的schedule子句來指定希望每個線程處理的塊大小。在下面的例子中,我指定了static調度方法,其大小爲chunk,用於指定每個線程應獲得的連續迭代次數。在這個簡單的例子中,每個線程將獲得每個8次迭代的塊(例如,線程0將得到迭代0-7,線程1迭代8-15等)。值得指出的是,如果你不關心塊分佈的順序(例如,如果你不關心線程0是否獲得第一塊),你可以用dynamic替換staticdynamic提供了在線程需要時將塊分配給線程的能力,而不是從一開始就將線程塊預分配給線程(在某些迭代比其他迭代花費更長時間時用於負載均衡)。有關調度方法的更多信息,請查看以下內容:

例子:

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

int main() { 
    int i; 
    int iterations = 32; 
    int num_threads = 4; 

#pragma omp parallel for schedule(static, 8) num_threads(num_threads) 
    for(i=0; i<iterations; i++) { 
    printf("thread %d: %d\n", omp_get_thread_num(), i); 
    } 

} 
+1

如果一個人不關心塊分佈的排序,而是關心性能,那麼'schedule(動態)'應該只能作爲修復負載不平衡的最後手段。與靜態調度相比,動態調度的開銷是巨大的。 –

1

你可以簡單地使用下面的代碼來實現這一目標。

#pragma omp parallel for num_threads(8) 
for(int y = 0; y < data_size_Y; y++) { 
    .... 
} 

通常我認爲長列表firstprivate是沒有必要的。根據你如何使用這些變量,其中大多數應該能夠被定義爲shared

+2

Downvoter,照顧來解釋你的票呢? –

+0

我沒有downvote,但據推測,對於常量來說,最好的做法是使用firstprivates而不是shared。根據我的經驗,使用firstprivate實際上確實快得多。 – Julius