Solution de contournement élégante (et typique) pour la réduction OpenMP sur les variables complexes en C ++?

Je réalise que la réduction n’est utilisable que pour les types de POD en C ++. Que feriez-vous pour mettre en œuvre une réduction pour un accumulateur de type complexe?

complex x(0.0,0.0), y(1.0,1.0); #pragma omp parallel for reduction(+:x) for(int i=0; i<5; i++) { x += y; } 

(notant que j’ai peut-être oublié une syntaxe). Il semble qu’une solution évidente serait de scinder les composants réels et imaginaires en doubles temporaires, puis de les accumuler. Je suppose que je recherche l’élégance, et cela semble… moins que joli. Serait-ce l’approche typique ici?

La solution de contournement typique en l’absence de réductions OpenMP définies par l’utilisateur est encore plus laide que ce que vous avez suggéré. Habituellement, avant la région parallèle, les gens créent un tableau d’autant d’éléments (au moins) qu’il y aura de threads dans la région, accumulent les résultats partiels séparément pour chaque thread en utilisant omp_get_thread_num() comme index du tableau et effectuent la réduction finale. des résultats accumulés dans une boucle après la région parallèle.

Autant que je sache, le comité linguistique OpenMP travaille à l’ajout de réductions définies par l’utilisateur à la spécification. Le problème sera donc résolu dans quelques années.

Désolé, OpenMP ne supporte tout simplement pas cela pour le moment. Malheureusement, vous devez procéder parallèlement à une réduction laide de ce que vous avez déjà décrit.

Cependant, si cette réduction parallèle est très fréquente, j’aimerais créer un constructeur similaire à parallel_reduce dans TBB. La mise en œuvre d’une telle construction est assez simple. Cilk plus a un object réducteur plus puissant, mais je n’ai pas vérifié s’il prenait en charge les logiciels non POD.

Pour votre information, ce type de ressortingction peut également être trouvé dans pragma threadprivate . J’ai testé avec VC ++ 2008/2010 et les compilateurs Intel (icc). VC ++ ne peut pas prendre en charge les utilisateurs threadprivate avec une structure / classe ayant un constructeur ou un destructeur (ou une variable scalaire nécessitant l’initialisation de l’appel de fonction), en générant une erreur: erreur C3057 , “initialisation dynamic des symboles” administrateur privé “”. Vous pouvez également lire ce lien MSDN . Cependant, la CSI accepte le cas de C3057. Vous pouvez voir, au moins, deux implémentations majeures sont tellement différentes.

Je suppose que soutenir la réduction parallèle sur les non-POD poserait le problème similaire ci-dessus. Afin de prendre en charge la réduction parallèle, chaque section parallèle doit allouer une variable locale au thread pour une variable de réduction. Donc, si une variable de réduction donnée est non-POD, ils peuvent avoir besoin d’appeler un constructeur défini par l’utilisateur. Cela pose le même problème que ce que j’ai mentionné dans le cas de C3057.