使用 32 位原子实现 64 位原子计数器
简介:
本文介绍了 64 位原子计数器的设计和实现,使用32 位原子操作。它旨在提供对共享计数器的高效、无锁访问,特别适合具有多个读取器和单个写入器的场景。
设计注意事项:
建议的设计基于“SeqLock”的概念,它利用 32 位生成计数,其中低位用作读锁
代码实现:
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); } };
设计评估:
替代解决方案:
需要注意的是,原子读-修改-写(RMW)操作对于增量操作。相反,更有效的方法是使用带有释放内存排序的纯加载和存储:
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); }
结论:
建议的实现提供了一个高效且正确的解决方案用于使用 32 位原子创建 64 位原子计数器。 SeqLock 设计确保计数器在无锁的情况下运行,同时允许多个读取器和单个写入器同时操作,而不会引入数据竞争。
以上是如何仅使用 32 位原子实现 64 位原子计数器?的详细内容。更多信息请关注PHP中文网其他相关文章!