2011-11-29 25 views
0

我正在嘗試使用OpenMP實現單生產者 - 多消費者模型(我知道我也可以去尋找更適合的升級線程)。使用OpenMP的消費者生產者模型

這裏是我的代碼,這是相當簡單,使用一個線程感知隊列類型:

bool producer_finished = false; 

#pragma omp parallel default(none) shared(producer_finished, buffer, datagen) 
{ 
    #pragma omp sections 
    { 
     #pragma omp section 
     { // single producer 

      while(datagen) { 
       DType data = datagen.next() 
       buffer.push(data); 
      } 

      producer_finished = true; 
      #pragma omp flush(producer_finished) 

     } // end omp section 

     #pragma omp section 
     { 
      #pragma omp for schedule(static, 1) 
      for (int i = 0; i < omp_get_max_threads() - 1; ++i) { 

       while (! producer_finished) { 

        #pragma omp critical(buffer) 
        { 
         DType = buffer.pop(); 
        } 

        processData(data); 
        outputData(data); 

        #pragma omp flush(producer_finished) 
       } 
      } // end omp for 
     } // end omp section 

    } //end omp sections 
} // end omp parallel 

這裏的問題是,直到緩衝區滿,但消費者永遠不會開始生產啓動和推動數據。如果我刪除「for pragma」部分,也會發生同樣的情況。你能看到我的方法有什麼問題嗎?

我也編譯期間得到這樣的警告:

warning: work-sharing region may not be closely nested inside of work-sharing, critical, ordered or master region 

它指的是在部分循環嵌套。在這種情況下,正確的做法是什麼?

感謝您的反饋。

編輯:剛剛發現this related question,set_omp_nested(1)沒有幫助我。我會嘗試把它放在單獨的函數中......

回答

0

OpenMP是專爲並行計算而設計的,它不是一個通用的線程庫。所以試圖用OpenMP做一個生產者/消費者循環就是使用錯誤的工具,恕我直言。

+0

好的,這也是我的印象,我想我會使用boost線程來實現它。我只想用現有代碼快速實現,因爲我已經知道一些OpenMP ...(儘管應該可以使用boost部分/任務) – fungs

0

您的OpenMP代碼在語法上是錯誤的。 這是編譯器告訴你的。 並行部分和並行循環都是工作共享結構,它們可能不會彼此嵌套嵌套。 您可以在for結構周圍添加一個內部並行循環,從而使用嵌套並行,您可能需要明確啓用它。

此外,使用flush指令是不夠的。 您還需要同步正在處理的數據。 非常推薦在沒有列表的情況下使用flush(如果有的話)。

您可能希望在www.openmp.org上向論壇提出OpenMp相關問題,與OpenMP專家對話。

最好的問候, 迪特

+1

謝謝,我使用boost線程實現了生產者 - 使用者模式,它的工作原理與魅力。對我而言,除非必須將基本的串行代碼與許多for循環並行化,否則OpenMP將停止運行。 – fungs

0

將整個#pragma omp解壓縮爲一個函數,並將其更改爲#pragma omg parallel for。

執行當前的#pragma omp並行激活與omp_set_nested(1)的嵌套並行。