2011-01-23 64 views
3

所以這裏的代碼:OpenMP的線程「違」 OMP屏障

#pragma omp parallel private (myId) 
{ 
    set_affinity(); 

    myId = omp_get_thread_num(); 

    if (myId<myConstant) 
    { 
    #pragma omp for schedule(static,1) 
    for(count = 0; count < AnotherConstant; count++) 
     { 
     //Do stuff, everything runs as it should 
     } 
    } 

#pragma omp barrier //all threads wait as they should 
#pragma omp single 
{ 
    //everything in here is executed by one thread as it should be 
} 
    #pragma omp barrier //this is the barrier in which threads run ahead 
    par_time(cc_time_tot, phi_time_tot, psi_time_tot); 
    #pragma omp barrier 
} 
//do more stuff 

我們解釋一下怎麼回事。在我的並行區域開始時,myId被設置爲private,以便每個線程都有其正確的線程ID。 set_affinity()控制哪個線程在哪個內核上運行。我遇到的問題涉及計劃的#pragma omp(靜態,1)。

塊:

if (myId<myConstant) 
    { 
    #pragma omp for schedule(static,1) 
    for(count = 0; count < AnotherConstant; count++) 
     { 
     //Do stuff, everything runs as it should 
     } 
    } 

表示了一些工作,我想通過myConstant-1分發超過一定數目的線程,0。在這些線程上,我想均勻地(以調度(靜態,1)的方式)分配循環的迭代。這一切都正確執行。

然後代碼進入一個區域,那裏的所有命令都按照它們應該執行的方式執行。但是,如果我指定myConstant爲2,那麼如果我使用3個或更多線程運行,則通過單個材質執行的所有操作都將正確執行,但id爲3或更大的線程不會等待單個內部的所有命令完成。

在單個內部調用一些函數,創建由所有線程執行的任務。 id爲3或更多的線程(通常爲myConstant或更多)繼續執行,執行par_time(),而其他線程仍在執行由單個執行的函數創建的任務。 par_time()只是爲每個線程打印一些數據。例如,如果我註釋掉schedule(static,1)的編譯指示omp,並且只讓一個線程執行for循環(例如將if語句更改爲if(myId == 0)),那麼一切正常。所以我只是不確定爲什麼上述線程繼續前進。

讓我知道如果有什麼困惑,這是一個特定的問題。我正在查看是否有人看到我的OMP流量控制缺陷。

+0

嗯,好吧,我發現有一個修復,但我不知道爲什麼。註釋掉if語句似乎解決了這個問題,只有通過AnotherConstant的線程0似乎在for循環中被使用。這是保證嗎?在for循環中可以使用帶有任何id的線程,或者通過AnotherConstant它將始終爲0。 – WtLgi 2011-01-23 01:09:39

回答

6

如果你看的OpenMP V3.0規範,2.5節工作分享結構,規定:

以下限制適用於 工作分享結構:

  • 每個工作共享區域必須由遇到團隊中的所有主題 或根本沒有。
  • 遇到的工作共享區域和屏障區域的序列必須 對於 團隊中的每個線程都是相同的。

通過具有工作共享的內如果您違反了這兩個限制,使你的程序不符合要求。根據規範,不符合要求的OpenMP程序具有「未指定」行爲。

至於哪些線程將用於執行for循環,調度類型爲「static,1」,第一個工作塊 - 在本例中爲count = 0 - 將分配給線程0.下一個塊(count = 1)將被分配給線程1等,直到所有塊被分配爲止。如果塊的數量多於線程,則分配將以循環方式在線程0重新啓動。您可以閱讀OpenMP規範中2.5.1循環結構的詳細說明,並在說明中討論計劃子句。