2012-04-13 137 views
4

我有這個找到最小和最大長度的循環,你可以看到我在查看OpenMP時有兩個值在這裏減少,我只能注意到它只提供了一個值的減少技巧。openmp reduce技術

for (size_t i = 0; i < m_patterns.size(); ++i) 
{// start for loop 
    if (m_patterns[i].size() < m_lmin)   
     m_lmin = m_patterns[i].size();   
    else if (m_patterns[i].size() > m_lmax)   
     m_lmax = m_patterns[i].size(); 
}// end for loop 

我可以做以下

#pragma omp parallel for reduction (min:m_lmin,max:m_lmax) 

,或者我應該重寫for循環兩個for循環一個最小和一個最大

另一個問題..我可以使用tbb容器,如OpenMP中的concurrent_vector

+0

爲了您的另外一個問題,看看這裏:http://stackoverflow.com/questions/7683204/tbb-concurrent-vector-with-openmp – 2012-04-13 15:51:36

回答

0

就openmp而言 - 官方規範可用(www.openmp.org)。但最後你的編譯器正在做所有的工作。所以回答你的問題可能是編譯器相關... 但是微軟提供http://msdn.microsoft.com/de-de/library/2etkydkz(v=vs.80).aspx

提示

#pragma omp parallel for reduction(min:m_lmin) reduction(max:m_lmax) 
+0

-1到MSDN的鏈接不會談論最大值,它確實不起作用。 – 2014-03-21 11:26:58

+0

你可以參考「http://www.techdarting.com/2013/06/openmp-min-max-reduction-code.html」這個鏈接獲得最小最大減少的更多細節。 – krishna 2014-03-23 20:26:03

2

OpenMP的從3.1,他們開始支持分&最大的降低動作。 OpenMP 3.1可從GCC 4.7獲得。您可以參考this link瞭解最小最大減量的詳細信息。

1

通過並行填充變量的私有版本,然後將它們合併到關鍵部分,可以實現自己的併發向量以及最小和最大約簡。這將在僅支持OpenMP 2.5(不支持最小和最大減少)的MSVC中起作用。但不管您的OpenMP版本是否支持最小和最大減少量,這都是一種有用的技術。

只要循環的項目數比線程數量大得多(或者項目的運行時間與合併相比較大),此方法就很有效。

#pragma parallel 
{ 
    int m_lmin_private = m_lmin; 
    int m_max_private = m_max_private; 
    #pragma omp for nowait 
    for (size_t i = 0; i < m_patterns.size(); ++i) { 
     if (m_patterns[i].size() < m_lmin_private)   
      m_lmin_private = m_patterns[i].size();   
     else if (m_patterns[i].size() > m_lmax_private)   
      m_lmax_private = m_patterns[i].size(); 
    } 
    #pragma omp critical 
    { 
     if (m_lmin_private<m_lmin)   
      m_lmin = m_lmin_private;  
     if (m_lmax_private>m_lmax)   
      m_lmax = m_lmax_private;      
    } 
} 

對於並行向量我們同樣的方法:

std::vector<int> vec; 
#pragma omp parallel 
{ 
    std::vector<int> vec_private; 
    #pragma omp for nowait //fill vec_private in parallel 
    for(int i=0; i<n; i++) { 
     vec_private.push_back(i); 
    } 
    #pragma omp critical 
    vec.insert(vec.end(), vec_private.begin(), vec_private.end()); 
}