2017-10-20 34 views
0

D'abord, gardez à l'esprit que je ne suis pas un utilisateur très fréquent d'OpenMP ... OK? Maintenant que nous sommes passés, y a-t-il une condition critical?
Je suis particulièrement intéressé par cette ligne dans une boucle for parallélisée:OpenMP conditionnel critique

(...) 

    #pragma omp critical 
    myMapOfVectors[i].push_back(someNumber); 

(...) 

Je voudrais l'avoir criticalsi et seulement si les fils en cours d'exécution de cette ligne spécifique ont la même i (parce que je expérimenté - et s'il vous plaît corrigez-moi ici si je me trompe - plusieurs threads repoussant au même vector n'est pas thread sûr et pourrait provoquer un segfault).

Répondre

0

Ce dont vous avez besoin est d'avoir un lock pour chaque index i.

// before you parallel region 
std::vector<omp_lock_t> myLocks(myMapOfVectors.size()); 
for (size_t i = 0; i < myLocks.size(); ++i) { 
    omp_init_lock(myLocks+i); 
} 

... 

omp_set_lock(myLocks[i]); 
myMapOfVectors[i].push_back(someNumber); 
omp_unset_lock(myLocks[i]); 

... 

// after your parallel region 
for (size_t i = 0; i < myLocks.size(); ++i) { 
    omp_destroy_lock(myLocks+i); 
} 

Une section critique est essentiellement juste une serrure simple, en ayant plusieurs verrous que vous êtes en émulant essence ayant une section critique pour chaque indice. N'oubliez pas que le verrouillage peut être assez lent (surtout s'il y a des collisions). Vous pouvez obtenir de meilleures performances si vous pouvez partitionner votre travail à l'avance (c'est-à-dire que chaque thread travaille sur un ensemble d'index différent i, ou chaque thread a sa propre copie de myMapOfVectors qui sera combinée plus tard).

+0

Merci pour votre réponse! J'apprécie votre solution, mais je m'attendrais à ce que des directives m'obligent à faire le gros du travail. Je veux dire, c'est pourquoi nous avons OpenMP, non? : P Pas une plainte envers vous, juste un critique à OpenMP ... –

+1

Parce que pragmas sont des directives de compilation, ils ne peuvent pas être utilisés pour synchroniser sur des objets tas dynamiquement alloués (dans le cas général au moins). Si vous implémentez votre propre objet stack (avec une allocation de mémoire fixe), vous pouvez utiliser '#pragma omp atomic' pour insérer des éléments en interne (l'insertion ne serait pas atomique, mais incrémenterait le nombre). – dlasalle