2017-01-11 80 views
3

我正在運行帶有動態負載平衡的openmp for for循環。我想打印每個線程在程序結束時處理多少個任務/迭代。 循環如下所示:使用動態調度計算openmp for循環的迭代次數

chunk=1; 
#pragma omp parallel for schedule(dynamic,chunk) private(i) 
for(i=0;i<n;i++){ 
//loop code 
} 
+0

'threadprivate'是最簡單的解決方案。 –

回答

3

沒有什麼更容易。剛剛拆分合並parallel for指令分成兩個獨立的結構,它允許您之前添加額外的代碼,並在循環後:

#pragma omp parallel 
{ 
    int iters = 0; 
    #pragma omp for schedule(dynamic,chunk) 
    for (int i = 0; i < n; i++) { 
     ... 
     iters++; 
    } 
    #pragma omp critical 
    printf("Thread %d did %d iterations\n", omp_get_thread_num(), iters); 
} 
+0

不應該在'printf'之前有'#pragma omp critical'。同樣,OP說「在程序結束時」,所以OP可能意味着他/她想要保存結果並在以後在並行區域之外打印它們。 –

+0

「沒有比這更容易的了。」 'threadprivate'更容易,也不需要改變代碼的結構。 –

+0

'threadprivate'需要一個靜態/全局變量,這會打開另一個蠕蟲。 –

0

對每個線程使用一個私人計數器。沒有其他辦法。

喜歡的東西

int workload[n_threads] = {0, ...}; 
#pragma omp parallel for schedule(dynamic) private(i) 
for(int i=0;i<n;i++){ 
    //loop code 
    workload[omp_get_thread_num()]++; 
} 
+2

...假分享... –

1

如果你真的想在你的程序中的外底打印迭代次數您並行區域或其他代碼(並避免虛假共享),簡單的解決方案是使用threadprivate

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

int iters; 
#pragma omp threadprivate(iters) 

int main(void) { 
    omp_set_dynamic(0); //Explicitly turn off dynamic threads 
    int i; 
    int n = 10000; 
    #pragma omp parallel for schedule(dynamic) 
    for(i=0; i<n; i++) { 
    iters++; 
    } 
    #pragma omp parallel 
    #pragma omp critical 
    printf("Thread %d did %d iterations\n", omp_get_thread_num(), iters); 
} 

這是一個複雜的解決方案,它還要求您更改代碼的結構。

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

int main(void) { 
    int i; 
    int n = 100; 
    int nthreads; 
    int *aiters; 
    #pragma omp parallel 
    { 
    nthreads = omp_get_num_threads(); 
    #pragma omp single 
    aiters = malloc(sizeof *aiters * nthreads); 
    int iters = 0; 
    #pragma omp for schedule(dynamic) 
    for(i=0; i<n; i++) { 
     iters++; 
    } 
    aiters[omp_get_thread_num()]=iters; 
    } 
    for(i=0; i<nthreads; i++) 
    printf("Thread %d did %d iterations\n", i, aiters[i]); 
    free(aiters); 
} 
+0

不保證您的第一個示例中的兩個並行區域將以相同數量的線程執行。 _dyn-var_必須顯式設置爲_false_。 –

+0

@HristoIliev,我修正了它,我認爲使用'omp_set_dynamic(0)'。我不知道可以在並行區域之間動態更改線程數量,而不必明確告訴OpenMP執行此操作。原則上可能是這樣,但我不知道我是否曾經在實踐中見過它。你有嗎? –

+0

@HristoIliev,你怎麼沒有指出[這裏](http://stackoverflow.com/questions/18719257/parallel-cumulative-prefix-sums-in-openmp-communicating-values-between-thread#comment27598031_18719257) 「時間表(靜態)具有由標準保證的特殊屬性,如可重複分配模式」。如果線程數量在並行區域之間動態變化,我不能依賴具有相同可重複分佈的時間表(靜態)。 –