Fonctions de barrière de mémoire dans le code multithread et quand les utiliser
Introduction
En multithread programmation, il est crucial de garantir la cohérence des données et la cohérence entre plusieurs threads. Intel fournit des fonctions intrinsèques, telles que _mm_sfence(), _mm_lfence() et _mm_mfence(), pour établir des barrières de mémoire et contrôler l'ordre de la mémoire. Comprendre quand utiliser ces fonctions est essentiel pour une optimisation efficace et efficiente du code.
_mm_sfence()/NT Stores
_mm_sfence() est couramment utilisé en conjonction avec des non- magasins temporels (NT). Les magasins NT sont faiblement ordonnés, ce qui signifie qu'ils garantissent uniquement que les données seront vidées en mémoire, mais pas nécessairement dans un ordre spécifique. Si vous devez vous assurer que les magasins NT deviennent visibles globalement par les autres threads, vous devez émettre une instruction _mm_sfence() après le magasin NT.
_mm_lfence()
Le L'instruction _mm_lfence() agit comme une barrière de chargement, empêchant l'exécution des charges suivantes avant que les charges précédentes ne soient retirées. Cependant, sur les processeurs x86, il est généralement inutile d'utiliser _mm_lfence() car le matériel garantit l'ordre de charge sans barrières explicites.
_mm_mfence()
_mm_mfence() est la barrière de mémoire la plus complète et établit une cohérence séquentielle. Il garantit que tous les chargements et magasins antérieurs deviennent globalement visibles avant que toute opération de mémoire ultérieure puisse s'exécuter. _mm_mfence() est principalement utile dans des scénarios spécifiques, tels que le lancement de votre propre implémentation de C11/C 11 std::atomic ou le contrôle de l'ordre des données stockées dans la mémoire persistante.
C 11 std :: atomic
Dans la plupart des cas, il est recommandé d'utiliser C 11 std::atomic au lieu d'implémenter manuellement des barrières de mémoire. C 11 std::atomic fournit des fonctions de haut niveau qui garantissent l'ordre et la cohérence de la mémoire sans avoir besoin de code assembleur explicite.
Stores NT et performances
C'est important Il convient de noter que les magasins NT sont conçus pour des cas d'utilisation spécifiques et peuvent avoir un impact sur les performances. Les opérations de stockage en général n'affectent pas la vitesse d'exécution visible, car elles sont mises en mémoire tampon dans le processeur. Cependant, dans les cas où la cohérence et l'ordre des données sont critiques, les magasins NT, en combinaison avec _mm_sfence(), peuvent être utilisés pour garantir le comportement correct du programme.
NT stocke et acquiert/libère la sémantique
Lors de l'utilisation de magasins NT, _mm_sfence() fournit une sémantique de version, garantissant que les opérations ultérieures dans d'autres threads ne deviennent visibles qu'après le magasin NT. De même, si le thread consommateur utilise une approche sémantique d'acquisition (par exemple, memory_order_acquire), _mm_sfence() garantit que tous les magasins NT précédents deviennent globalement visibles avant l'accès aux données acquises.
Barrières et exécution dans le désordre
Les barrières de mémoire, notamment _mm_sfence(), _mm_lfence() et _mm_mfence(), peuvent affecter l'exécution dans le désordre dans les environnements modernes. Processeurs. Ces processeurs tentent d'exécuter des instructions en parallèle pour une efficacité accrue. Cependant, lorsqu'une barrière de mémoire est rencontrée, le processeur doit s'assurer que toutes les opérations de mémoire antérieures sont terminées avant d'autoriser les opérations suivantes, ce qui pourrait diminuer les gains de performances dus à une exécution dans le désordre.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!