openmp减少技术

时间:2012-04-13 13:17:02

标签: c++ parallel-processing openmp reduce tbb

我有这个for循环找到最小和最大长度,你可以看到我在看这个OpenMP时有两个值可以减少我只能注意到它只为一个值提供了缩减技术。

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循环,一个用于最小值,一个用于最大值

另一个问题..我可以在OpenMP

中使用tbb容器,例如concurrent_vector

3 个答案:

答案 0 :(得分:2)

从OpenMP 3.1开始,他们开始支持min&amp;最大减少操作。 OpenMP 3.1可从GCC 4.7获得。您可以参考this link 了解最大限度减少的详细信息。

答案 1 :(得分:1)

您可以通过并行填充变量的私有版本然后在关键部分合并它们来滚动自己的并发向量以及最小和最大缩减。这将在MSVC中工作,MSVC仅支持OpenMP 2.5(不支持最小和最大缩减)。但无论您的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());
}

答案 2 :(得分:0)

就openmp而言 - 可以获得官方规范(www.openmp.org)。但最后你的编译器正在做所有的工作。所以你的问题的答案可能是编译器相关的...... 但是,Microsoft正在提供http://msdn.microsoft.com/de-de/library/2etkydkz(v=vs.80).aspx

提示

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