2011-10-05 124 views
6

爲什麼intel編譯器不能讓我指定只應由主線程執行openmp parallel for塊中的某些動作?OpenMP「master」編譯指令不能被「parallel for」編譯指令包含

如果沒有這種功能,我該怎麼做?

我試圖做的是更新通過回調的進度條在平行於:

long num_items_computed = 0; 

#pragma omp parallel for schedule (guided) 
for (...a range of items...) 
{ 
    //update item count 
    #pragma omp atomic 
     num_items_computed++; 

    //update progress bar with number of items computed 
    //master thread only due to com marshalling 
    #pragma omp master 
     set_progressor_callback(num_items_computed); 

    //actual computation goes here 
    ...blah... 
} 

我想只有主線程調用回調,因爲如果我不強制執行(比如通過使用omp critical代替,以保證只有一個線程使用回調一次)我得到以下運行時異常:

The application called an interface that was marshalled for a different thread. 

...因此,讓所有的回調在主線程的願望。

在此先感謝。

回答

6
#include <omp.h> 
void f(){} 
int main() 
{ 
#pragma omp parallel for schedule (guided) 
    for (int i = 0; i < 100; ++i) 
    { 
     #pragma omp master 
     f(); 
    } 
    return 0; 
} 

編譯器錯誤C3034 OpenMP的 '主人' 指令不能直接嵌套在 '平行的' 指令 Visual Studio 2010中的OpenMP 2.0

可能是這樣:

long num_items_computed = 0; 

#pragma omp parallel for schedule (guided) 
for (...a range of items...) 
{ 
    //update item count 
    #pragma omp atomic 
     num_items_computed++; 

    //update progress bar with number of items computed 
    //master thread only due to com marshalling 
    //#pragma omp master it is error 
    //#pragma omp critical it is right 
    if (omp_get_thread_num() == 0) // may be good 
     set_progressor_callback(num_items_computed); 

    //actual computation goes here 
    ...blah... 
} 
+0

這似乎是工作,謝謝。我擔心主線程可能與所有工作線程不同......因此回調將永遠不會執行......在omp規範中是可以想象的嗎? –

+0

如果迭代次數很大,則不會注意到差異。並且在循環之後添加:if(omp_get_thread_num()== 0)set_progressor_callback(num_items_computed); –

+0

from standart OpenMP about pragma omp parallel for():「循環結構指定一個或多個關聯循環的迭代將由團隊中的線程在其隱式任務的上下文中並行執行。迭代分佈在執行循環區域綁定的並行區域的團隊中已存在的線程上。「 –

3

之所以你得到的錯誤是因爲主線程在代碼到達#pragma omp master行時大部分時間都沒有。 例如,讓我們的代碼從阿爾喬姆:

#include <omp.h> 
void f(){} 
int main() 
{ 
#pragma omp parallel for schedule (guided) 
    for (int i = 0; i < 100; ++i) 
    { 
     #pragma omp master 
      f(); 
    } 
    return 0; 
} 

如果代碼將編譯,下面會發生:

假設線程0開始(主線程)。它達到了實際上說「主人,做下面的一段代碼」的編譯指示。它是主人可以運行的功能。 但是,當線程1或2或3等達到那段代碼時會發生什麼?

主指令告訴當前/收聽團隊主線程必須執行f()。但團隊是一個單一的線程,並沒有主人在場。該方案不知道過去該做什麼。

這就是爲什麼我認爲主人不允許進入for循環。

master directive替換爲if (omp_get_thread_num() == 0)是可行的,因爲現在程序會說「如果您是主人,請執行此操作,否則忽略」。