使用 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 操作需求的替代设计是使用 volatile uint64_t 和 std::atomic
以上是如何仅使用 32 位原子变量实现 64 位原子计数器?的详细内容。更多信息请关注PHP中文网其他相关文章!