2014-05-08 20 views
5

我不知道如何使一个结构或对象为THREADPRIVATE,我在做什么产生一个错误:如何在OpenMP中将对象或结构定义为threadprivate?

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) 

它产生一个错误:

error C3057: 'myPoint' : dynamic initialization of 'threadprivate' symbols is not currently supported

它意味着,当前的OpenMP编译器不支持此作一个结构THREADPRIVATE?或者我所做的是错误的。 有没有其他的方法来传递一个结构或对象?

这里是我的代码剩余部分:

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

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

    } 
+0

你是用C编译器还是C++编译的?我看到你将它标记为两者。它看起来可能不喜欢构造函数。详细说来,它看起来可能不会像调用构造函数来初始化数据,而不是来自'.text'的静态副本。 – rjp

+0

我正在使用vC++,你的意思是手动传递它更好吗? –

+0

在我看来'threadprivate'变量需要静态初始化。我不知道如何去做,而不是抛开构造函数,只写一个函数'initPoint2d(point2d&p,int inX,int inY)'。这违反了面向对象的“规则”,但我相信。我是一个C人。 – rjp

回答

3

在C++与方法结构是一类在默认情况下是公共的。这不是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的purpuse是每个线程都有一个对象/类型的私有版本,并且这些值在并行区域之间保持不变。您可以通过删除指向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; 
    } 
} 
2

你在你的代码中做了什么是完全正确的。引用OpenMP标准(重点是我的):

A threadprivate variable with class type must have:

  • an accessible, unambiguous default constructor in case of default initialization without a given initializer;
  • an accessible, unambiguous constructor accepting the given argument in case of direct initialization;
  • an accessible, unambiguous copy constructor in case of copy initialization with an explicit initializer.

粗体字似乎正是你的情况。

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

+0

GCC工作正常。你做'extern point2d myPoint; #pragma ompthreadprivate(myPoint) point2d myPoint;'这是GCC中的一个工作示例http://coliru.stacked-crooked.com/a/f156e0122760fe12 –

+0

@Zososon这里是关键字static [似乎会触发错误]( http://coliru.stacked-crooked.com/a/2e861eb25b53073a)在非POD类型上 – Massimiliano

+0

将静态更改为extern并删除myPoint在该示例中的版本,并且它可以工作http://coliru.stacked-crooked.com/ a/a274f6a4c5f63568 –

相关问题