并行任务中的C ++ OpenMP变量可见性

时间:2010-07-20 17:10:28

标签: c++ multithreading openmp

不明白,我在哪里弄错了。如果编译时没有openmp支持,则代码可以正常工作。但是使用openmp变量似乎会出现错误的可见性。

我有以下意图。每个线程都有自己的max_private,在其中找到本地最大值。然后在关键部分找到全局最大值。

#include <iostream>
#include <vector>

typedef std::vector<long> Vector;

long max(const Vector& a, const Vector& b)
{
    long max = 0;
    #pragma omp parallel
    {
        long max_private = 0;

        #pragma omp single
        {
            for (   Vector::const_iterator a_it = a.begin();
                    a_it != a.end();
                    ++a_it)
            {
                #pragma omp task
                {
                    for (   Vector::const_iterator b_it = b.begin();
                            b_it != b.end();
                            ++b_it)
                    {
                        if (*a_it + *b_it > max_private) {
                            max_private = *a_it + *b_it;
                        }
                    }
                }
            }
        }

        #pragma omp critical
        {
            std::cout << max_private << std::endl;
            if (max_private > max) {
                max = max_private;
            }
        }
    }
    return max;
}

int main(int argc, char* argv[])
{
    Vector a(100000);
    Vector b(10000);
    for (long i = 0; i < a.size(); ++i) {
        a[i] = i;
    }
    for (long i = 0; i < b.size(); ++i) {
        b[i] = i * i;
    }

    std::cout << max(a, b) << std::endl;

    return 0;
}

我不想使用parallel,因为后者我将使用不支持随机访问迭代器的数据结构。

我使用的是g ++ - 4.4编译器。

3 个答案:

答案 0 :(得分:2)

在OpenMP论坛上得到了详细的答案。 http://openmp.org/forum/viewtopic.php?f=3&t=912&start=0

必须制作max_private threadprivate。

答案 1 :(得分:0)

我认为你需要的是变量的一些属性。默认情况下,所有变量都是共享的,并且您希望max_private是每个线程,您可以愉快地将“private”子句添加到其声明中(它可能会更快一些)。

对于max,你需要将它放在omp块中,如果它仍然无法正常工作,则用'shared'标记它(尽管它应该没问题)

所以,我认为你想要#pragma omp parallel private(max_private)并将两个变量放在主omp块之外。

答案 2 :(得分:0)

你需要的是减少openmp以找到最大值。它在OpenMP 3.0中可用

减少for

long max(const Vector& a, const Vector& b)
{
    long max_val = 0;  // <- change the name for clarity
    #pragma omp parallel reduction(max : max_val)
    { 
      [...] 
      #pragma omp critical
      {
        std::cout << max_private << std::endl;
        if (max_private > max_val) {
            max_val = max_private;
        }
      }
    }
    return max_val; 
}

max_val在每个线程中都是私有的,并且在循环结束时减少发生并返回每个open_mp线程的最大值。