2014-05-08 10 views
5

nie wiem jak zrobić struct lub przedmiot threadprivate, co robię generuje błąd:Jak zdefiniować obiekt lub strukturę jako threadprivate w OpenMP?

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

Oświadczam statyczną strukturę i starać się im threadprivate

static point2d myPoint; 
    #pragma omp threadprivate(myPoint) 

to generuje błąd:

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

Czy oznacza to, że prąd OpenMP kompilator nie obsługuje tego dokonać threadprivate struct? Albo to, co robię, jest złe. Czy istnieje inny sposób przekazywania struktury lub obiektu?

Oto część reszta moich kodów:

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

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

    } 
+0

Czy kompilujesz to z kompilatorem C lub C++? Widzę, że oznaczyłeś to jako jedno i drugie. Wygląda na to, że może nie lubić konstruktora. Aby to rozwinąć, wygląda na to, że może nie lubić wywoływania konstruktora w celu zainicjowania danych, zamiast statycznej kopii z '.text'. – rjp

+0

Używam vC++, czy myślisz, że lepiej przekazać to ręcznie? –

+0

Po prostu wydaje mi się, że zmienne "threadprivate" muszą zostać zainicjalizowane statycznie. Nie jestem pewien, jak to zrobić bez odrzucenia konstruktora i po prostu napisanie funkcji 'initPoint2d (point2d & p, int inX, int inY)'. Jest to jednak sprzeczne z "zasadami" OO. Jestem facetem w stylu C. – rjp

Odpowiedz

3

W C++ struct z metod jest klasa gdzie domyślnym jest publiczna. To nie jest plain-old-data (POD). MSVC seems to imply that it can handle threadprivate objects (i.e. non-POD), ale nie mogę tego zmusić do działania. Zrobiłem dostać pracę w GCC tak:

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

Ale jest praca wokół którego będzie współpracować z MSVC (jak GCC i ICC). Możesz używać wskaźników wątku prywatnego.

Właściwością threadprivate jest posiadanie prywatnej wersji obiektu/typu dla każdego wątku i utrzymywanie wartości między równoległymi regionami. Możesz to zrobić, delcaringując wskaźnik do point2d, czyniąc ten wątekprywatnym, a następnie przydzielając pamięć dla prywatnego wskaźnika dla każdego wątku w regionie równoległym. Upewnij się, że usuniesz przydzieloną pamięć podczas ostatniego połączenia równoległego.

#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

To, co robisz w swoim kodzie, jest całkowicie poprawne. Cytując standard OpenMP (podkreślenie moje):

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.

Ten napisany czcionką pogrubioną wydaje się być dokładnie tym, co należy.

Zachowanie, które napotkasz, wydaje się być missing feature or a bug in the compiler. O dziwo, nawet GCC seems to have problem with that, podczas gdy Intel twierdzi, że działa dobrze.

+0

GCC działa dobrze.Robisz 'extern point2d myPoint; #pragma ompthreadprivate (myPoint) point2d myPoint; 'Oto działający przykład w GCC http://coliru.stacked-crooked.com/a/f156e0122760fe12 –

+0

@Zboson Oto słowo kluczowe static [wydaje się powodować błąd] (http://coliru.stacked-crooked.com/a/2e861eb25b53073a) na typach innych niż POD – Massimiliano

+0

Zmień dane statyczne na zewnętrzne i usuń elementy myPoint w tym przykładzie i działa http://coliru.stacked-crooked.com/ a/a274f6a4c5f63568 –

Powiązane problemy