2013-11-25 124 views
-1

所以我有一個循環,我遍歷一個向量的元素,在每個元素上調用一個函數,並且如果它符合某個標準,我將它推到一個列表中。將循環轉換爲OpenMP

my_list li; 

for (auto itr = Obj.begin(); itr != Obj.end(); ++itr) { 
    if ((*itr).function_call()) 
     li.push_back((*itr); 
} 

我一直在思考的方法來優化我的程序,我碰到OpenMP來了,但很多的示例代碼是很難效仿。

有人可以通過如何轉換上述循環以並行利用多個內核來引導我嗎?

謝謝。

回答

1

有你需要

  1. 如果你正在使用OpenMP 3.0(或以上),你可以並行的for循環#pragma omp for,如果您使用的是照顧到並行化的代碼片斷幾點舊版本的OpenMP,您需要使用for循環訪問具有索引的向量。
  2. 你需要警惕li.push_back((*itr);語句的鎖,或設置爲關鍵部分
  3. 如果FUNCTION_CALL是不是一個很慢的功能或您的載體不包含這麼多項目,它可能沒有必要進行並行線程創建將引入開銷。

所以僞代碼實現將

my_list li; 
#pragma omp for 
for (auto itr = Obj.begin(); itr != Obj.end(); ++itr) { 
    if ((*itr).function_call()) 
    { 
     #pragma omp critical CRIT_1 
     { 
      li.push_back((*itr); 
     } 
    } 
}
+2

不使用無名稱關鍵結構是一種很好的做法。您應該爲其添加一個名稱,以確保關鍵僅保護li數據結構。否則,關鍵可能會影響代碼段中不需要相互排斥的其他關鍵部分。 –

+0

我會通過一個指向數據開始的指針迭代矢量並運行索引。對於(T * =&obj [0],size_t i = 0,size_t size = obj.size(); ++ i {} – egur

+0

很好的解決方法,謝謝邁克爾,現在編輯解決方案 – ikikenis

0

的時機已經到來,討論有效的方式使用容器類,如std ::清單或std :: vector的使用OpenMP(因爲OP希望使用OpenMP列表優化他的代碼)。讓我列舉四種提高效率的方法。

  1. 填充容器中並行段中的一個關鍵塊
  2. 讓每個線程的容器的專用版本,並行填補他們,然後在關鍵部分
  3. 不要使用它們合併STL容器。 STL的設計並不考慮效率。相反,要麼寫你自己的或使用Agner Fog's containters這是爲了效率而設計的。例如,不是使用堆來分配內存,而是使用內存池。
  4. 在某些特殊情況下,也可以並行合併容器的私有版本。

第一種情況的示例代碼在接受的答案中給出。這破壞了使用線程代碼的大部分目的,因爲每次迭代都會填充關鍵部分中的容器。

第二種情況的示例代碼可以在C++ OpenMP Parallel For Loop - Alternatives to std::vector找到。而不是重新發布代碼在這裏讓我舉一個例子,使用第三種情況昂納霧的容器類

DynamicArray<int> vec; 
#pragma omp parallel 
{ 
    DynamicArray<int> vec_private; 
    #pragma omp for nowait //fill vec_private in parallel 
    for(int i=0; i<100; i++) { 
     vec_private.Push(i); 
    } 
    //merging here is probably not optimal 
    //Dynamic array needs an append function 
    //vec should reserve a size equal to the sum of size each vec_private 
    //then use memcpy to append vec_private into vec in a critcal section 
    #pragma omp critical 
    { 
     for(int i=0; i<vec_private.GetNum(); i++) { 
      vec.Push(vec_private[i]); 
     } 
    }   
} 

最後,在特殊情況下,例如使用直方圖(大概在實驗粒子物理學中最常見的數據結構) ,也可以並行地合併私有數組。對於直方圖而言,這相當於數組縮減。這有點棘手。顯示如何執行此操作的示例可在Fill histograms (array reduction) in parallel with OpenMP without using a critical section