J'ai un problème étrange lorsque je construis un de nos projets dans une configuration de débogage 64 bits. Il semble produire un comportement étrange qui ressemble un peu à un seul itérateur est incrémenté plusieurs fois. Je l'ai réduit au code de test suivant: Cependant, le test de taille échoue fréquemment qui implique d'en quelque sorte l'insertion de tout le contenu du vecteur - et beaucoup de poking À cela, il semble que les itérateurs de vecteur sont incrémentés plus d'une étape à la fois. Il est tout à fait difficile de dire que cela n'a pas tendance à se produire si l'on se brise avec le débogueur. P> La conclusion évidente au tirage serait que ce n'est pas threadsafe, mais ma compréhension est que cela devrait être parce que cela devrait être parce que La seule variable modifiée est Il y a beaucoup de choses qui résoudront le problème immédiat: p> Ceci est compilé sous MSVC ++ 2008 SP1, avec la mise en œuvre STL fournie par compilateur. P> Peut-on perdre une lumière sur ce qui se passe ici? Merci d'avance pour toutes les astuces - je suis assez soulevée :) p> Edit: Au cas où il n'est pas clair, je ne cherche pas une "solution rapide" pour faire fonctionner ce code; Comme indiqué ci-dessus, je connais depuis pas quelques-uns de ceux-ci. Ce que je veux comprendre, c'est pourquoi ce problème se produit en premier lieu. P> Editer 2: code fonctionne correctement lors de la compilation avec GCC. P> P> s code> qui a une portée locale. P>
() code> appel li>
#define has_iterator_debugging 1 code> li>
3 Réponses :
ressemble à un bogue dans la mise en œuvre de VS 2008 de OpenMP et / ou de STL. Avec vs 2010, il n'est pas reproduit; De plus, il n'est pas reproduit avec les en-têtes de compilateur d'Intel et de VS 2008, ce qui me fait penser que le bogue est plus probable dans la prise en charge OpenMP dans le compilateur VC ++. P>
Ne semble pas le réparer pour moi ...? _Secure_scl n'a pas semblé avoir beaucoup d'impact ici, sauf que cela prend parfois que les choses ne sont pas fausses juste avant que l'hilarité s'ensuit.
Je suis d'accord avec Darhuk, je suggérerais de marquer s code> privé
Comme je l'ai noté dans les commentaires, cela ne fonctionne pas; s est défini à l'intérieur de la boucle afin que le code ci-dessus ne compile même pas. Il devrait y avoir une copie de s code> par fil de toute façon.
Les variables déclarées à l'intérieur de la portée de la boucle sont automatiquement privées. Tout comme le compteur de boucle I dans ce cas.
Je n'ai jamais écrit de code OpenMP, mais j'ai fait beaucoup de programmation multi-filetées, mon instinct peut donc être correct ou non.
La méthode insert () sur l'ensemble n'est pas du fil de sécurité, et il échoue car plusieurs threads l'invoquent simultanément. Vous devez verrouiller (ou certains équivalents OpenMP) pour garantir les inserts sont effectués de manière séquentielle. P>
EDIT:
Essayez ceci p>
Ce n'est pas le même ensemble - il devrait y avoir un ensemble par fil, car il est créé à l'intérieur de la région parallèle. Afin tant que la méthode insert () est réentrante, cela devrait suffire.
J'ai essayé un équivalent à cela en utilisant les directives CODE> OMM Critiques CODE> qui le résoudent, mais n'explique pas ce qui se passe mal. Je ne pense pas que je devrais avoir à ajouter une serrure à la version de production de cela puisqu'elle fonctionne bien sans entrées 32 bits.
Oh bien sûr. J'aurais dû comprendre que cela ne pouvait pas être aussi simple que cela.
arrive sans optimisation allumé?
Pourrait-il être dû au fait que votre
S code>,
commence code> et
fin (code> variables sont partagés sur toutes les discussions? Essayez d'ajouter
privé (s), privé (début), privé (fin) code> après
oomp parallèle pour code>.
Darhuuk: L'ajout de ces clauses privées ne compile pas ("identifiant non déclaré"). Ma compréhension est que toute variable déclarée à l'intérieur de la boucle est implicitement privée de toute façon?
FAZO: n'arrive que sans optimisation (/ OD). AT / O1 Le problème disparaît.
Pour le #pragma omp parallel pour, dois-je avoir quelque chose sur mon système pour que cela fonctionne réellement? J'ai essayé de compiler votre solution pour X64 dans le VS10 dans le débogage, le dirigé et n'avait aucun problème; Donc je ne suis pas sûr.
Leetightshade: vous devez activer OpenMP dans les propriétés du projet pour que le pragma signifie n'importe quoi (Propriétés de configuration> C / C ++> Langue> Support OpenMP ou Ajout / OpenMP à la ligne de commande)
Juste une supposition sauvage, mais il se peut que OpenMP détecte que
s.insert (début, fin); code> est une boucle également, tente de le parallémenter mais échoue car elle utilise le
! = < / Code> La syntaxe que AFAIK n'est pas prise en charge comme une condition de terminaison pour un
pour code> boucle ...
@Eugen: OpenMP ne fait pas ou tente de faire une parallélisation automatique; Il doit y avoir un pragme qui marque la boucle comme parallèle. Les compilateurs peuvent parallèler des boucles automatiquement - par ex. Le compilateur d'Intel a une option pour cela; Mais je ne suis pas au courant d'une option similaire dans le compilateur MSVC.
Je soupçonne fortement un bogue dans la sécurité du fil de la mise en œuvre de MS2008. Essayez-le sans OpenMP et un filetage simple?
SEHE: Mes pensées sont similaires, mais je marche un peu soigneusement avant de les blâmer. Merci pour l'idée - je vais l'essayer quand de retour au travail demain.
@Peter: bonne attitude. Fwiw j'ai testé cela avec
g ++ - {4.5 | 4.6} {-d_glibcxx_parallel} {-g} -fopenmp -lgomp code> (
{} code> désignant les options) fonctionnant sous la valeur de Valgrind - Outil = Memcheck et Valgrind --Tool = Hélicite sans résultats anormaux (sauf que fonctionnant sous valgrind Memcheck semblait empêcher le multitraitement, verrouillant efficacement le travail à 1 noyau, mais c'est probablement le verrouillage des emballages Malloc / Gratuits).
SEHE: ont essayé d'utiliser le threading Windows qui le corrige, il semblerait que quelque chose ne va pas avec leur mise en œuvre OpenMP. Semble fonctionner si je déplace l'intérieur de la boucle en une fonction distincte - peut-être que le code OpenMP généré des champs de variables incorrectement?