web-dev-qa-db-fra.com

Qu'est-ce qu'une barrière de mémoire?

Que signifie utiliser une barrière de mémoire explicite?

103
yesraaj

Pour des gains de performances, les processeurs modernes exécutent souvent des instructions dans le désordre pour utiliser au maximum le silicium disponible (y compris la lecture/écriture de la mémoire). Parce que le matériel applique l'intégrité des instructions, vous ne le remarquez jamais dans un seul thread d'exécution. Cependant, pour plusieurs threads ou environnements avec une mémoire volatile (E/S mappées en mémoire par exemple), cela peut entraîner un comportement imprévisible.

Une barrière/barrière de mémoire est une classe d'instructions qui signifie que les lectures/écritures de mémoire se produisent dans l'ordre que vous attendez. Par exemple, une "clôture complète" signifie que toutes les lectures/écritures avant la clôture sont validées avant celles après la clôture.

Notez que les clôtures de mémoire sont un concept matériel. Dans les langages de niveau supérieur, nous sommes habitués à traiter les mutex et les sémaphores - ceux-ci peuvent très bien être mis en œuvre en utilisant des clôtures de mémoire à bas niveau et l'utilisation explicite de barrières de mémoire n'est pas nécessaire. L'utilisation de barrières de mémoire nécessite une étude approfondie de l'architecture matérielle et plus courante dans les pilotes de périphériques que dans le code d'application.

La réorganisation du CPU est différente des optimisations du compilateur - bien que les artefacts puissent être similaires. Vous devez prendre des mesures distinctes pour empêcher le compilateur de réorganiser vos instructions si cela peut provoquer un comportement indésirable (par exemple, utilisation du mot clé volatile en C).

99
Gwaredd

Copie ma réponse à une autre question, Quels sont les trucs qu'un processeur fait pour optimiser le code? :

Le plus important serait la réorganisation de l'accès à la mémoire.

En l'absence de barrières mémoire ou d'instructions de sérialisation, le processeur est libre de réorganiser les accès mémoire. Certaines architectures de processeur ont des restrictions sur la quantité qu'elles peuvent réorganiser; Alpha est connu pour être le plus faible (c'est-à-dire celui qui peut le plus réorganiser).

Un très bon traitement du sujet peut être trouvé dans la documentation source du noyau Linux, à Documentation/memory-obstacles.txt .

La plupart du temps, il est préférable d'utiliser des primitives de verrouillage de votre compilateur ou bibliothèque standard; ceux-ci sont bien testés, devraient avoir toutes les barrières de mémoire nécessaires en place et sont probablement assez optimisés (l'optimisation des primitives de verrouillage est délicate; même les experts peuvent parfois se tromper).

15
CesarB

D'après mon expérience, il se réfère à un barrière de mémoire , qui est une instruction (explicite ou implicite) pour synchroniser l'accès à la mémoire entre plusieurs threads.

Le problème se produit dans la combinaison de compilateurs agressifs modernes (ils ont une liberté incroyable pour réorganiser les instructions, mais ne connaissent généralement rien de vos threads) et des processeurs multicœurs modernes.

Une bonne introduction au problème est la déclaration " La déclaration de verrouillage à double vérification est rompue ". Pour beaucoup, c'était le réveil qu'il y avait des dragons.

Les barrières de mémoire pleine implicites sont généralement incluses dans les routines de synchronisation des threads de plate-forme, qui en couvrent le cœur. Cependant, pour la programmation sans verrouillage et la mise en œuvre de modèles de synchronisation légers et personnalisés, vous n'avez souvent besoin que de la barrière, ou même d'une barrière à sens unique.

6
peterchen

Wikipedia sait tout ...

La barrière de mémoire, également connue sous le nom de membar ou de barrière de mémoire, est une classe d'instructions qui oblige une unité centrale de traitement (CPU) à appliquer une contrainte de commande sur les opérations de mémoire émises avant et après l'instruction de barrière.

Les processeurs utilisent des optimisations de performances qui peuvent entraîner une exécution dans le désordre, notamment des opérations de chargement de mémoire et de stockage. La réorganisation des opérations de mémoire passe normalement inaperçue dans un seul thread d'exécution, mais provoque un comportement imprévisible dans les programmes simultanés et les pilotes de périphériques, sauf si soigneusement contrôlé. La nature exacte d'une contrainte de classement dépend du matériel et est définie par le modèle de mémoire de l'architecture. Certaines architectures fournissent plusieurs barrières pour appliquer différentes contraintes de classement.

Les barrières de mémoire sont généralement utilisées lors de l'implémentation d'un code machine de bas niveau qui fonctionne sur une mémoire partagée par plusieurs appareils. Ce code comprend des primitives de synchronisation et des structures de données sans verrouillage sur les systèmes multiprocesseurs et des pilotes de périphériques qui communiquent avec le matériel informatique.

1
Omar Kooheji