现代 C++ 从零构建无锁队列
Building a Fast Lock-Free Queue in Modern C++ from Scratch
在多线程环境下,传统的 std::mutex 加 std::queue 方案在高频并发时会因上下文切换导致性能崩塌。我在优化 Xlux 软件渲染器时,决定从零构建一个 Fast Lock-Free Queue。通过利用 Compare And Swap (CAS) 指令,用乐观重试替代悲观阻塞,让线程无需陷入内核态等待。虽然对大多数应用而言互斥锁已足够,但在高频交易、实时游戏引擎等极端场景下,消除锁竞争带来的微秒级延迟至关重要。
在重负载竞争下,你的程序最终会将绝大部分 CPU 预算消耗在内核中来回切换线程,而那个你寄予厚望的标准库队列,开始变得像早高峰的停车场一样拥堵。
- moffers
无意批评,但文中确实有不少拼写和语法错误。读的时候突然意识到这是真人写的,反而让人耳目一新。我甚至有点受启发,想把自己写作时的拼写检查也关了。
- rfgplk
文章不错。不过粗略一看,代码里有几个问题:你的析构函数似乎因为支持自定义 deleter 而可能导致虚假或重复释放(建议检查一下);另外,你似乎过度使用了 seq_cst,即便很多时候并不需要(在队列中应尽可能避免使用);最后,FastQueueNodeSlot 类没有对齐(而且 64 字节对齐仅适用于 amd64 CPU,Apple Silicon 的要求更大)。
- nly
一旦你开始使用 atomic cmpxchg,可扩展性就会大打折扣,因为它意味着需要重试循环(无论是内部实现还是由用户处理)。
你最不想看到的就是所有线程都因为 cmpxchg 失败(无论是虚假失败还是其他原因)而在共享缓存行上自旋。
现实中的替代方案表明,仅使用 atomic xchg 的解决方案可以扩展到数百个线程。