2017-11-25 174 views
0

我對OpenMP相當陌生,並且我嘗試了一些Monte Carlo代碼並行化。OpenMP - 在for循環中產生並終止線程時的開銷

我有一個for循環必須連續運行它調用new_value()功能:

for(int i = 0; i < MAX_VAL; i++) 
    new_value(); 

該功能打開每次調用並行區域:

void new_value() 
{ 
#pragma omp parallel default(shared) 
{ 
    int thread_rank = omp_get_thread_num(); 

#pragma omp for schedule(static) 
    for(int i = 0; i < N; i++) 
     arr[i] = update(thread_rank); 
} 
} 

哪些工作,但有與線程的產卵和終止相關的大量開銷;我想知道是否有人知道一種方法來產生線程(並達到thread_rank)之前進入循環沒有並行循環?

有問同樣的事情的幾個問題,但他們要麼是錯誤的或者無人接聽,其實例包括:

This question它要求一個類似的事情,答案建議創建一個並行區域,然後使用#pragma omp single上最外層的循環,但正如「Joe C」在答案評論中所說的那樣,這是行不通的。我可以確認該程序只是掛起。

This question詢問確切同樣的事情,但(取消選中)的答案是剛剛parallelise運行循環4000 * num_threads最外層的環既不是什麼提問者想和我想要的東西。

回答

0

第二個問題的答案其實是正確的。

#pragma omp parallel 
for(int i = 0; i < MAX_VAL; i++) 
    new_value(); 

void new_value() 
{ 
    int thread_rank = omp_get_thread_num(); 

#pragma omp for schedule(static) 
    for(int i = 0; i < N; i++) 
     arr[i] = update(thread_rank); 
} 

是正確的,正是你想要的。它與你問題中的代碼具有相同的語義。區別在於只有一個平行區域,並且整個團隊現在計算循環變量i。請注意,外循環是而不是以工作共享方式並行(omp parallel for)。

所以這段代碼運行時,num_threads線程將執行環頭,一旦new_value並達到omp for所有與他們的私人i == 0。他們將分享內部循環的工作。然後他們會一直等到所有人都完成了隱式屏障的循環,然後增加他們的私有i,然後重複......我希望現在清楚的是,這與內部循環的行爲相同,並且線程管理開銷較小。

+0

這很有道理,謝謝你的好解釋。我確實有一些後續問題(如果你不介意):我將如何讓每個線程以我原本以爲的方式執行for-loop,即num_threads * MAX_VAL次? – BodneyC

+0

實際上它實際上是被執行了'num_threads * MAX_VAL',但是由於工作共享,內部循環迭代只執行了'MAX_VAL * N'次。因此,除去內部的'omp for'會導致內部循環體執行'num_threads * MAX_VAL * N'次這樣的執行。 – Zulan

+0

現貨,這是非常有道理的。再次感謝。 – BodneyC