如何在OpenMP中将对象或结构定义为threadprivate?

时间:2014-05-08 20:40:41

标签: c++ struct openmp private

我不知道如何将struct或object作为threadprivate,我正在做的事情会产生错误:

    struct point2d{
        int x;
        int y;
        point2d(){
            x = 0;
            y = 0;
        }
        //copy constructor
        point2d(point2d& p){
            x = p.x;
            y = p.y;
        }
    };      

我声明了一个静态结构并尝试使它们成为threadprivate

    static  point2d myPoint;
    #pragma omp threadprivate(myPoint)

它会产生错误:

  

错误C3057:'myPoint':目前不支持'threadprivate'符号的动态初始化

这是否意味着当前的openmp编译器不支持这个来构建一个struct threadprivate?或者我正在做的事情是错的。 有没有其他方法来传递结构或对象?

这是我的代码的其余部分:

    void myfunc(){
        printf("myPoint at %p\n",&myPoint);
    }

    void main(){
    #pragma omp parallel
       {
           printf("myPoint at %p\n",&myPoint);
           myfunc();
       }

    }

2 个答案:

答案 0 :(得分:5)

在C ++中,带有方法的结构体是一个默认为public的类。这不是plain-old-data (POD)MSVC seems to imply that it can handle threadprivate objects (i.e. non-POD)但我似乎无法让它发挥作用。我确实让它在GCC中工作:

extern point2d myPoint;
#pragma omp threadprivate(myPoint)
point2d myPoint;

但是有一项工作可以与MSVC(以及GCC和ICC)一起使用。您可以使用threadprivate指针。

threadprivate的目的是为每个线程提供一个对象/类型的私有版本,并使值在并行区域之间保持不变。您可以通过将指针指向point2d,制作该threadprivate,然后为并行区域中的每个线程的私有指针分配内存来实现。确保在上次并行呼叫时删除已分配的内存。

#include <stdio.h>
#include <omp.h>

struct point2d {
    int x;
    int y;
    point2d(){
        x = 0;
        y = 0;
    }
    //copy constructor
    point2d(point2d& p){
        x = p.x;
        y = p.y;
    }
};      

static point2d *myPoint;
#pragma omp threadprivate(myPoint)

int main() {

    #pragma omp parallel 
    {
        myPoint = new point2d();
        myPoint->x = omp_get_thread_num();
        myPoint->y = omp_get_thread_num()*10;
        #pragma omp critical
        {
            printf("thread %d myPoint->x %d myPoint->y %d\n", omp_get_thread_num(),myPoint->x, myPoint->y);
        }
    }   
    #pragma omp parallel
    {
        #pragma omp critical
        {
            printf("thread %d myPoint->x %d myPoint->y %d\n", omp_get_thread_num(),myPoint->x, myPoint->y);
        }
        delete myPoint;
    }
}

答案 1 :(得分:2)

您在代码中执行的操作完全正确。引用OpenMP标准(强调我的):

  

具有类类型的threadprivate变量必须具有:

     
      
  • 默认初始化时没有给定初始化程序的可访问,明确的默认构造函数;
  •   
  • 一个可访问的,明确的构造函数接受   直接初始化时给定的参数;
  •   
  • 在使用显式初始化程序进行复制初始化时,可访问的,明确的复制构造函数。
  •   

粗体的那个似乎就是你的情况。

您遇到的行为似乎是missing feature or a bug in the compiler。奇怪的是,即使是GCC seems to have problem with that,英特尔也声称可以正常工作。