【问题标题】:Making static class members threadprivate in OpenMP在 OpenMP 中使静态类成员线程私有
【发布时间】:2018-05-08 13:48:05
【问题描述】:

我正在使用 C++ 中的 OpenMP,并尝试将线程私有类的静态成员变量设为私有。 一个非常简化的示例代码示例如下所示

#include <omp.h>
#include<iostream>

template<class numtype>
class A {
public:
    static numtype a;
    #pragma omp threadprivate(a)
};

template<class numtype>
numtype A<numtype>::a=1;

int main() {

 #pragma omp parallel
 {

  A<int>::a = omp_get_thread_num();

  #pragma omp critical
  {
    std::cout << A<int>::a << std::endl;
  }
 } /* end of parallel region */    
}

如果我尝试使用 gcc 编译器编译此代码,我会收到错误消息

threadprivatetest.cpp:8:27: 错误:'a' 尚未声明

#pragma omp threadprivate(a)

如果我使用英特尔 C++ 编译器,代码会编译并运行。 当我搜索错误时,我已经找到了这个问题的一些答案。

Using the OpenMP threadprivate directive on static instances of C++ STL types

但是,因为这是一个更大的项目,我想在其中使用 gcc 编译器,并且链接的帖子已经有 6 年的历史了。 今天有没有可能用 gcc 编译器编译这样的代码? 有人可以详细解释旧帖子中提到的解决方法,因为我无法理解吗?

感谢您的帮助!

【问题讨论】:

  • 嗯。您可以将模板想象成宏而不是现成的代码。因此,问题可能是 #pragma omp threadprivate(a) 失败,因为 a 在模板被实例化之前还没有“真实存在”。您是否尝试将#pragma omp threadprivate(a) 移动到A&lt;int&gt;::a = omp_get_thread_num(); 之后的行。或者,您可以显式地实例化您的模板(对于类型int)并在此之后移动#pragma omp threadprivate(a)。在这种情况下,您可能必须对a 应用一些范围。 (请考虑到我对 OMP 一无所知。我只是在大声思考选项。)
  • 刚刚查看了您提供的链接。与您的代码不同的是,链接的示例代码将#pragma omp 应用于(模板化)类的实例。 (他们有存储空间。)您尝试将#pragma omp 应用于类模板的成员。 (它(还没有)存储(直到模板被实例化)。)我可以想象前者没有问题,但后者超出了 OMP 的能力。
  • 我最近又查了一下这个问题。您当时可能就认为这超出了 OMP 的能力范围。然而看起来,将成员变量作为指向对象的指针解决了这个问题。
  • 我没听懂你的最后一句话“但是看起来,使成员变量成为指向对象的指针解决了这个问题。”你能edit你的问题并添加你的新样本(这似乎有效)吗? (除了修正小错别字,请不要过多更改现有文本。)如果您自己找到答案,欢迎发布:SO: Can I answer my own question?

标签: c++ static openmp private


【解决方案1】:

下面的代码可以正常工作,并且完成了我最初打算做的事情。

#include <omp.h>
#include<iostream>

template<class numtype>
class A {
public:
  static numtype* a;
  #pragma omp threadprivate(a)
};

template<class numtype>
numtype* A<numtype>::a=nullptr;

template class A<int>;

int main() {
  #pragma omp parallel
  {

    A<int>::a = new int;
    *A<int>::a = omp_get_thread_num();

    #pragma omp critical
    {
      std::cout << *A<int>::a << std::endl;
    }
  } /* end of parallel region */
}

如您所见,不同之处在于 a 现在是指向 numtype 而不是 numtype 的指针。

【讨论】:

    猜你喜欢
    • 2014-09-02
    • 2011-02-24
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    相关资源
    最近更新 更多