2014-09-12 410 views
3

我想使用openmp來加速下面的代碼。如何在while循環中使用openmp while

該代碼只是爲了解釋操作,而不是真實的。

Iterator iterator(records); 
while(iterator.next()) 
{ 
    int current_id = iterator.current_row_index(); 
    bool result = index.find(records[current_id]) 
    if (result == false) 
     if (index.insert(records[current_id]) == false) 
      break; 
} 
return iterator.current_row_index(); 

索引由所有線程共享。

這裏有一些想法從我:

  • 使用OMP並行指令,確保線程才能運行。
  • 使用omp關鍵指令來操作迭代器。
  • 使用omp critical指令在索引中查找並插入索引。

但我真的懷疑加速,因爲幾乎所有的操作都很危險。

有沒有一些建議,以加快使用openmp的代碼?

謝謝!

+0

是迭代器只是一個前向迭代器?它可以用作隨機訪問迭代器嗎? – Anton 2014-09-12 10:59:35

+0

@Anton它現在只是一個前向迭代器,但我可以修改它以支持後向。但它不能隨機訪問。我不想修改迭代器代碼。 – b8flowerfire 2014-09-12 11:09:31

+0

你想在串行while循環找到的第一個索引或任何索引處停下來嗎? – Walter 2014-09-12 14:05:50

回答

4

回答問題的標題,並假設沒有其它問題(下面討論),一般的while循環與通過正向迭代休息可以翻譯這樣的:

Iterator iterator(records); 
#pragma omp parallel 
{ 
    #pragma omp single nowait 
    { 
     while(iterator.next()) 
     { 
      int current_id = iterator.current_row_index(); 
      #pragma omp task firstprivate(current_id) 
      { 
       if (should_stop(current_id))) { 
        // below requires OpenMP 4.0 
        #pragma omp cancel parallel 
       } 
      } 
     } 
    } 
} 

然而,存在在你的問題中更復雜的問題實際上應該得到單獨的問題。

  1. index表的使用表明,它不是線程安全的。所以,你不能安全地訪問它並同時插入。由於它是while循環的唯一工作,除非你切換到併發哈希表,如在例如提供的concurrent_unordered_map中,否則沒有意義使它平行。 ,,

  2. 當插入可以返回false並且爲什麼當它發生時需要行的索引時,它並不清楚。可能在切換到另一個表執行之後,根本沒有必要。否則,一般來說,多個線程可以同時對您的狀況做出「回答」,並且必須將它們同步並減少到單個結果。最簡單的OMP-ish方式是使用臨界區來選擇和存儲結果,否則存在引入競爭條件的危險。

+0

'current_id'應該是'firstprivate'。 – 2014-09-12 13:57:22

+0

是的,錯過了這個,謝謝 – Anton 2014-09-12 13:59:21

+1

你也可以完全省略這個子句,因爲'private'變量在'task'構造中被默認爲'firstprivate'。 – 2014-09-12 14:00:54