2011-01-28 21 views
2

我正在考慮一個線程池將執行代碼塊的設計,它可能包含OpenMP語句(主要是並行)。 (類似於:How to deal with OpenMP thread pool contention我猜)。 我的問題是,如果OpenMP並行區域每次都由不同的線程執行,它會導致問題或導致性能不佳。在線程池中執行的OpenMP代碼

編輯:

目標將是Linux操作系統(GCC)和Windows(MSVC)。

當我的第一個原型完成時(這將受到我在這裏得到的答案的影響),我會對它進行基準測試。

下面是一個簡單的例子:

class Task 
{ 
public: 
    void doTask() 
    { 
     #pragma omp parallel 
     { 
      // do work in parallel 
     } 
    } 
}; 

現在想象你創建的Task一個實例給它一個線程池(線程0,...,螺紋-N)。一個線程執行doTask()。之後,您再次將相同的Task對象放入線程池,並再次......。 所以doTask()(和平行部分)將由不同的線程執行。我想知道這是否由OpenMP有效地處理(例如,該部分的線程不會每次都重新創建)。

+0

關於什麼編譯器? – 2011-01-28 15:58:20

+2

根據我的經驗優化代碼,有一種方法可以知道某件事是否會提高性能:進行基準測試。如果實施過於複雜,思考和創建假設只有在某些事情很慢時纔有用。創建一個真實的測試演示並進行基準測試 – 2011-01-28 16:36:33

回答

4

Vitor的評論是正確的。很難判斷這是否會導致問題,因爲答案取決於許多因素(例如,數據佈局,訪問數據的方式,緩存大小,運行的處理器類型以及列表繼續)。

我可以說的是,你可能會也可能不會得到這個工作。 OpenMP規範 - 以及大多數其他線程模型 - 並沒有說明模型將如何或如果「很好地結合在一起」。例如,儘管一些OpenMP實現爲底層實現使用pthread,但除非實現已經完成了一些工作,否則用戶不能直接調用pthreads庫並使其與OpenMP一起使用。當前的例子是gcc bug 42616(pthread中的OMP循環導致崩潰)。另一個例子是英特爾,其編譯器支持許多並行模型,但努力讓它們一起工作。既然你還沒有說你要使用什麼編譯器,我只能說,在你承諾做大事之前,先試一下一小段示例代碼,看它是否有效。

我曾嘗試過這樣的事情。我使用了pthreads,然後使用OpenMP構造。我發現,對於我的應用程序,它工作正常。當遇到OpenMP並行區域時,每個pthread被認爲是一個初始線程。然後,OpenMP運行時爲該區域創建其他線程並運行該區域。由於大多數OpenMP實現不會銷燬線程,但是在遇到另一個區域時將它們放在空閒池中以供重用時,開銷似乎很好 - 但之後我在該地區做了大量工作。所以它可以工作 - 但你必須小心。