29 votes

Paranoïa multithread

C'est une question complexe, réfléchissez bien avant de répondre.

Considérez la situation. Les deux fils (un lecteur et un écrivain) à accéder à une seule global int. Est-il sécuritaire? Normalement, je réponds sans réfléchir, oui!

Cependant, il me semble que Herb Sutter ne le pense pas. Dans ses articles sur l'efficacité de la simultanéité, il parle d'un imparfait sans verrouillage de la file d'attente et la version corrigée.

À la fin du premier article et le début de la deuxième, il parle rarement considérée comme un trait de variables, l'ordre d'écriture. Int sont atomiques, bon, mais les services de renseignements ne sont pas nécessairement ordonné ce qui pourrait détruire tout sans verrouillage de l'algorithme, y compris mon scénario ci-dessus. Je suis entièrement d'accord que la seule façon de garantir corriger le comportement multithread sur toutes les plateformes actuelles et futures est d'utiliser atomics(AKA les barrières de la mémoire) ou les mutex.

Ma question; est d'écrire ré-odering jamais un problème sur un matériel réel? Ou est le multithread paranoïa juste d'être pédant?
Ce sur classique monoprocesseur systèmes?
Ce sujet de plus simple, les processeurs RISC comme un intégré power-pc?

Précisions: je suis plus intéressé par ce que M. Sutter a déclaré à propos du matériel (processeur/cache) la réorganisation de la variable écrit. Je peux arrêter l'optimiseur de casser le code avec des commutateurs du compilateur ou de la main de l'inspection de l'assemblée de post-compilation. Cependant, j'aimerais savoir si le matériel peut encore gâcher le code dans la pratique.

25voto

Jason Cohen Points 36475

Votre idée de l'inspection de l'assemblée n'est pas assez bon; la réorganisation peut se produire au niveau du matériel.

Pour répondre à votre question "est-ce un problème sur le matériel:" Oui! En fait, j'ai couru sur ce problème moi-même.

Est-il OK pour contourner le problème avec les systèmes monoprocesseur ou à d'autres cas? Je dirais "non" parce que de cinq ans à partir de maintenant, vous pourriez avoir besoin de courir sur de multi-cœur, après tout, et puis la recherche de tous ces lieux va être difficile (impossible?).

Une exception: un Logiciel conçu pour matériel embarqué applications où en effet, vous avez complètement le contrôle sur le matériel. En fait, j'ai "triché" de ce genre dans ces situations sur, par exemple, d'un processeur ARM.

9voto

Eclipse Points 27662

Yup - utilisation de la mémoire des barrières pour empêcher la réorganisation de l'instruction en cas de besoin. Dans certains compilateurs C++, le mot clé volatile a été élargi pour insérer mémoire implicite obstacles pour tous les lire et à écrire - mais ce n'est pas une solution portable. (De même avec le Contrefil* Api win32). Vista ajoute même quelques nouveaux finement Entrelacés Api qui vous permettent de spécifier de lecture ou d'écriture de la sémantique.

Malheureusement, C++ dispose d'un tel lâche modèle de mémoire que n'importe quel type de code comme cela va être non-portable, dans une certaine mesure, et vous aurez à écrire des versions différentes pour différentes plates-formes.

5voto

Chris Jester-Young Points 102876

Comme vous l'avez dit, en raison de la réorganisation effectuée au niveau du cache ou du processeur, vous avez en fait besoin d'une sorte de barrière de mémoire pour assurer une bonne synchronisation, en particulier pour les multi-processeurs (et en particulier sur les plates-formes non x86). (On me donne à croire que les systèmes à processeur unique n'ont pas ces problèmes, mais ne me citez pas à ce sujet --- je suis certainement plus enclin à jouer en toute sécurité et à faire l'accès synchronisé de toute façon.)

5voto

Rob Walker Points 25840

Nous avons couru dans le problème, mais sur des processeurs Itanium où l'instruction réorganisation est plus agressif que le x86/x64.

La solution était d'utiliser un Contrefil instruction puisqu'il n'y avait (à l'époque), aucun moyen de dire au compilateur de manière simple, mais une barrière d'écriture après la cession.

Nous avons vraiment besoin d'extension du langage de traiter avec cela proprement. Utilisation de composés volatils (si pris en charge par le compilateur) est trop gros grains pour le cas où vous essayez de presser autant de performances, d'un morceau de code que possible.

4voto

Henk Points 1418

est-ce toujours un problème sur un matériel réel?

Absolument, surtout avec le passage à plusieurs noyaux actuels et futurs Processeurs. Si vous êtes dépendant ordonné l'atomicité de mettre en œuvre les fonctionnalités de votre application et vous sont pas en mesure de garantir cette exigence par l'intermédiaire de votre plate-forme choisie ou l'utilisation de primitives de synchronisation, sous toutes les conditions, par exemple le client se déplace d'un single-core CPU multi-core CPU, alors vous êtes en attente pour un problème de se produire.

Citant la visée de Herb Sutter article (le second)

Commandé atomique variables sont définies de différentes manières sur les plates-formes et environnements. Par exemple:

  • volatile en C#/.NET, comme en volatile int.
  • volatile ou * Atomique* en Java, comme en volatile int, AtomicInteger.
  • atomic<T> dans C++0x, le prochain Standard ISO C++, comme en atomic<int>.

Je n'ai pas vu comment C++0x met en œuvre commandée atomicité donc je ne suis pas en mesure de préciser si la prochaine fonctionnalité du langage est une pure mise en œuvre de bibliothèque ou s'appuie sur des modifications à la langue aussi. Vous pourriez examiner la proposition tendant à voir si il peut être incorporé en tant que non-standard extension de votre outil de la chaîne jusqu'à ce que la nouvelle norme est disponible, il peut même être d'ores et déjà disponibles pour votre situation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X