OpenMP 减少技术

openmp reduce technique

本文关键字:技术 OpenMP      更新时间:2023-10-16

我有这个 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中使用像concurrent_vector这样的tbb容器吗

从OpenMP 3.1开始,他们开始支持最小和最大缩减操作。OpenMP 3.1 可从 GCC 4.7 获得。您可以参考此链接以获取最小最大减少的更多详细信息。

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

就 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)