4

I have this for loop that finds minimum and maximum length, as you can see I have two values to reduce here while looking at OpenMP I can only notice that it provides reduction technique for only one value.

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 

can I do the following

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

or should I rewrite the for loop to two for loops one for the minimum and one for the maximum

another question .. can I use tbb containers like concurrent_vector in OpenMP

Mysticial
  • 464,885
  • 45
  • 335
  • 332
aTm
  • 79
  • 2
  • 10

3 Answers3

2

From OpenMP 3.1 they started support of min & max reduction operation. OpenMP 3.1 is available from GCC 4.7. You can refer this link for further details of min max reduction.

krishna
  • 413
  • 2
  • 10
  • 25
1

You can roll-your-own concurrent vector as well as min and max reductions by filling private versions of the variables in parallel and then merging them in a critical section. This will work in MSVC which only supports OpenMP 2.5 (which does not support min and max reductions). But irrespective of whether your version of OpenMP supports min and max reductions this is a useful technique to learn.

This method is efficient as long as the number of items you loop over is much larger than the number of threads (or the time run over the items is large compared to the merging).

#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;                     
    }
}

For concurrent vectors us the same method:

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());
}
Z boson
  • 32,619
  • 11
  • 123
  • 226
0

As far as openmp is concerned - an official specification is available ( www.openmp.org ). But finally your compiler is doing all the work. So the answer to your question may be compiler related... However Microsoft is offering http://msdn.microsoft.com/de-de/library/2etkydkz(v=vs.80).aspx

suggesting

#pragma omp parallel for reduction(min:m_lmin) reduction(max:m_lmax)
Matthias
  • 3,458
  • 4
  • 27
  • 46
  • -1 the link to MSDN does not talk about max and it is indeed not working. – levzettelin Mar 21 '14 at 11:26
  • You can refer "http://www.techdarting.com/2013/06/openmp-min-max-reduction-code.html" this link for further details of min max reduction. – krishna Mar 23 '14 at 20:26