Implémentation d'un compteur atomique 64 bits avec des atomes 32 bits
Introduction :
Cet article traite de la conception et de la mise en œuvre d'un compteur atomique 64 bits utilisant un compteur atomique 32 bits. opérations. Il vise à fournir un accès efficace et sans verrouillage à un compteur partagé, particulièrement adapté aux scénarios avec plusieurs lecteurs et un seul écrivain.
Considérations de conception :
Le proposé la conception est basée sur le concept de « SeqLock », qui exploite un nombre de générations de 32 bits avec un bit faible utilisé comme verrou de lecture mécanisme.
Mise en œuvre du code :
class counter { atomic<uint32_t> lo_; atomic<uint32_t> hi_; atomic<uint32_t> gen_; uint64_t read() const { auto acquire = memory_order_acquire; uint32_t lo, hi, gen1, gen2; do { gen1 = gen_.load(acquire); lo = lo_.load(acquire); hi = hi_.load(acquire); gen2 = gen_.load(acquire); } while (gen1 != gen2 || (gen1 & 1)); return (uint64_t(hi) << 32) | lo; } void increment() { auto release = memory_order_release; gen_.fetch_add(1, release); uint32_t newlo = 1 + lo_.fetch_add(1, release); if (newlo == 0) { hi_.fetch_add(1, release); } gen_.fetch_add(1, release); } };
Évaluation de la conception :
Solution alternative :
Il est important de noter que les opérations atomiques de lecture-modification-écriture (RMW) peuvent ne pas être nécessaires pour l'opération d'incrémentation . Au lieu de cela, une approche plus efficace consiste à utiliser des charges et des magasins purs avec un ordre de mémoire de version :
void increment() { auto release = memory_order_release; uint64_t count = lo_.load(release) | (uint64_t(hi_.load(release)) << 32); count++; lo_.store(count & uint32_t(-1), release); hi_.store((count >> 32) & uint32_t(-1), release); }
Conclusion :
La mise en œuvre proposée fournit une solution efficace et correcte pour créer un compteur atomique 64 bits utilisant des atomes 32 bits. La conception SeqLock garantit que le compteur fonctionne sans verrous tout en permettant à plusieurs lecteurs et à un seul écrivain de fonctionner simultanément sans introduire de courses de données.
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!