不要只懂 CAS:手把手带你手写面向 AI 推理的无锁 MPMC 队列
去年底我在做一个 LLM 推理服务的性能调优,8 个线程往一个请求队列里塞 inference request,然后 GPU worker 从另一头取。标准套路。我先跑了一版std::mutex+std::condition_variable的 baseline,perf stat 一看——2.1M ops/sec,还行。然后我换上了团队里一个同事写的"lock-free queue",号称无锁高性能。结果跑出来1.5M ops/sec。比 mutex 版慢了将近 30%。我当时以为是 benchmark 写错了,又反复确认了三遍,结果是稳定复现的。一个所谓的"无锁"队列,在实际推理服务场景下,被最朴素的 mutex 队列按在地上摩擦。后来我花了两天时间把那个 lock-free queue 的代码逐行拆开看,问题出在两个地方:第一,head 和 tail 两个原子变量挤在同一条 cache line 上,每次 CAS 操作都在触发跨核的缓存失效风暴;第二,所有的compare_exchange_weak全部用的memory_order_seq_cst,在 x86 上这意味着每次写操作都要插入一条MFENCE,把 store buffer 整个刷一遍。这件事让我重新审视了一个被行业反复念叨但很少有人真正理解的概念:Lock-free 的本质不是"快",而是"进度保证"(progress guarantee)。它保证