首页 > 后端开发 > C++ > 如何仅使用 32 位原子变量实现 64 位原子计数器?

如何仅使用 32 位原子变量实现 64 位原子计数器?

Mary-Kate Olsen
发布: 2024-12-11 17:38:19
原创
716 人浏览过

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

使用 32 位原子变量实现 64 位原子计数器

问题:

使用32位设计并实现64位原子计数器原子变量。计数器有一个写入器(信号处理程序)和多个读取器。

代码:

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);
    }
};
登录后复制

答案:

提供的代码是使用 32 位原子变量的 64 位原子计数器的正确实现。它使用一种称为 SeqLock 的技术,该技术采用生成计数来保持计数器高半部分和低半部分的一致性。

读取操作在处理时使用循环来获取计数器的正确状态读者和作者之间潜在的竞争条件。写入操作以原子方式递增计数器的高位和低位部分,使用内存排序来确保正确的行为。

改进的实现:

虽然提供的代码是正确的,可以对其进行改进以获得更好的性能和效率:

  • 而不是对计数器有效负载使用原子 RMW 操作,它们可以替换为普通加载和存储,以避免不必要的开销。
  • 序列计数器也可以用普通加载和存储来维护,因为它只需要单调递增而不需要原子更新。

替代设计:

完全消除原子 RMW 操作需求的替代设计是使用 volatile uint64_t 和 std::atomic 的联合;多变的。易失性部分可用于读取和写入值,而原子变量可用于更新序列计数器。这种方法为正确行为提供了必要的保证,同时还优化了性能。

以上是如何仅使用 32 位原子变量实现 64 位原子计数器?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板