【问题标题】:C++ OpenMP variable visibility in parallel tasks并行任务中的 C++ OpenMP 变量可见性
【发布时间】:2010-07-20 17:10:27
【问题描述】:

不明白,我哪里弄错了。如果在没有 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;
}

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

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

【问题讨论】:

    标签: c++ multithreading openmp


    【解决方案1】:

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

    必须将 max_private 线程设为私有。

    【讨论】:

      【解决方案2】:

      我认为您需要的是变量的一些属性。默认情况下,所有变量都是共享的,并且由于您希望 max_private 是每个线程的,您可以愉快地在其声明中添加 'private' 子句(那样可能会快一点)。

      对于 max,您需要将其放在 omp 块中,如果仍然无法正常工作,则将其标记为“共享”(尽管应该没问题)

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

      【讨论】:

      • 我已经尝试了您在第三段中的建议,但它对我不起作用。这是确保我理解正确的差异: 9c9,10 long max_private = 0; > #pragma omp parallel private(max_private) 11,12c12 max_private = 0;
      • 看起来任务中的 max_private 永远不会复制回每个线程本地的 max_private
      • 嗯。不确定 - 但我会尝试将 'private(max_private)' 添加到 '#pragma omp task' 指令中。
      【解决方案3】:

      您需要减少 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 线程的最大值。

      【讨论】:

        猜你喜欢
        • 2021-09-20
        • 1970-01-01
        • 1970-01-01
        • 2015-04-17
        • 2020-12-08
        • 2020-09-09
        • 2011-06-09
        • 1970-01-01
        • 2019-04-27
        相关资源
        最近更新 更多