Maison > développement back-end > C++ > Comment implémenter un compteur atomique 64 bits en utilisant uniquement des variables atomiques 32 bits ?

Comment implémenter un compteur atomique 64 bits en utilisant uniquement des variables atomiques 32 bits ?

Mary-Kate Olsen
Libérer: 2024-12-11 17:38:19
original
716 Les gens l'ont consulté

How to Implement a 64-bit Atomic Counter Using Only 32-bit Atomic Variables?

Implémentation d'un compteur atomique 64 bits avec des variables atomiques 32 bits

Question :

Concevoir et implémenter un compteur atomique 64 bits utilisant des variables atomiques 32 bits. Le compteur a un seul écrivain (gestionnaire de signal) et plusieurs lecteurs.

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);
    }
};
Copier après la connexion

Réponse :

Le code fourni est une implémentation correcte d'un compteur atomique 64 bits utilisant des variables atomiques 32 bits. Il utilise une technique connue sous le nom de SeqLock, qui utilise un décompte de générations pour maintenir la cohérence des moitiés haute et basse du compteur.

L'opération de lecture utilise une boucle pour acquérir l'état correct du compteur lors de la manipulation. conditions de course potentielles entre lecteurs et écrivains. L'opération d'écriture incrémente atomiquement les parties haute et basse du compteur, en utilisant l'ordre de la mémoire pour garantir un comportement correct.

Implémentation améliorée :

Bien que le code fourni soit correct , il peut être amélioré pour de meilleures performances et efficacité :

  • Au lieu d'utiliser des opérations RMW atomiques pour la charge utile du compteur, elles peuvent être remplacées avec des charges et des magasins simples pour éviter des frais généraux inutiles.
  • Le compteur de séquence peut également être maintenu avec des charges et des magasins simples, car il doit seulement être augmenté de manière monotone et non mis à jour de manière atomique.

Conception alternative :

Une conception alternative qui élimine complètement le besoin d'opérations RMW atomiques consiste à utiliser une union d'un élément volatile uint64_t et un std::atomic variable. La partie volatile peut être utilisée pour lire et écrire la valeur, tandis que la variable atomique peut être utilisée pour mettre à jour le compteur de séquence. Cette approche apporte les garanties nécessaires à un comportement correct tout en optimisant les performances.

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal