L'endroit où des barrières de mémoire sont requises est en utilisant des mécanismes de synchronisation du noyau dans un environnement SMP - généralement pour des raisons de performances. Il existe une barrière de mémoire implicite dans toute opération de synchronisation du noyau (par exemple des sémaphores de signalisation, des mutations de verrouillage et de déverrouillage) et une commutation de contenu pour se prémunir contre les risques de cohérence des données. Je viens de me retrouver avec des implémentations (modérément) portables de la barrière de mémoire (ARM et x86), et j'ai trouvé que l'arborescence des sources Linux était la meilleure source pour cela. Linux a des variantes SMP des macros mb()
, rmb()
et wmb()
- qui, sur certaines plateformes, entraînent des barrières plus spécifiques (et éventuellement moins coûteuses) que les variantes non-SMP.
Cela ne semble pas être un problème sur x86 et en particulier ARM où, bien que les deux sont mis en œuvre de la même manière.
C'est ce que j'ai chipé ensemble des fichiers d'en-tête linux (adapté pour ARMv7 et processeurs x86/x64 non anciennes)
#if defined(__i386__) || defined(__x64__)
#define smp_mb() asm volatile("mfence":::"memory")
#define smp_rmb() asm volatile("lfence":::"memory")
#define smp_wmb() asm volatile("sfence" ::: "memory")
#endif
#if defined(__arm__)
#define dmb() __asm__ __volatile__ ("dmb" : : : "memory")
#define smp_mb() dmb()
#define smp_rmb() dmb()
#define smp_wmb() dmb()
#endif
Naturellement, barboter avec des barrières de mémoire a le risque connexe que le code résultant est pratiquement impossible à tester, et tous les bugs qui en résultent seront obscurs et difficiles à reproduire conditions de course:/
Il y a, incidemment, une très bonne description des barrières de mémoire dans le Linux kernel documentation.
Salut Aib! Je ne suis pas en mesure de vous dire maintenant pourquoi cela est nécessaire. Je lis à propos de "éviter de réordonner" problème et je vois le code qui n'utilise pas de verrou du tout .. Je regarde ici http://www.cs.umd.edu/~pugh/java/memorymodel/DoubleCheckedLocking .html comme point de départ ,, – user311906
Ah, je vois. Ils essaient d'éviter de synchroniser toute la méthode (ce qui est la solution la plus simple, quoique plus lente). – aib
Remarque: «Modifier la sémantique pour exiger que la libération d'un verrou soit une barrière de mémoire complète entraînerait des pénalités de performance. Une autre solution plus simple et plus lente ici. Pour autant que je sache (je suis trop fatigué, désolé), la solution proposée sépare les barrières des serrures pour augmenter les performances. Je pense que vous allez avoir besoin d'une barrière de mémoire de bas niveau (c'est-à-dire une instruction unique, non portable) ici. – aib