Daily Technical Tracking

每日科技追踪 · 2026-9-11

2026年9月11日(周五) · 技术 / 产品 / 公司

每日追踪
← 返回首页

C++自旋锁四步优化5.7倍

David Álvarez Rosa 发布了一篇 C++ 自旋锁优化的完整实录:把一个朴素实现从四线程竞争下的 246 纳秒/操作 压到 43 纳秒(5.7 倍加速),封装功耗从 64.92 J 降到 11.92 J(5.4 倍节能)。测试负载是把计数器递增的 pinned 线程工作负载,测量维度包括延迟、缓存命中率、分支误预测与 RAPL 能耗计数器。

第一步:内存序优化。初始版本只用一个 std::atomic_bool 循环 exchange(true),无竞争时 3.14ns,四线程却暴涨到 246ns——perf 计数器显示 L1 数据缓存未命中率从 1.27% 飙到 61.73%,每次失败的交换都在核间弹跳缓存行。改用 acquire/release 内存序后,解锁路径从带锁读改写变成普通 store,四线程延迟降到 131ns,能耗降到 34.45J。

第二步:test-and-test-and-set。让等待者在交换失败后改为对 relaxed load 自旋,并插入 _mm_pause() 标记自旋等待——等待者不再每次迭代都写缓存行,四线程延迟进一步降到 120ns。第三步:指数退避。按照 Intel 优化手册,每次重试把 pause 次数翻倍直到上限 64,错开各核的唤醒节奏,避免所有核同时猛击同一把锁——最终 43ns、L1 未命中降到 12.88%、能耗 11.92J。

作者同时给出了冷静的边界提醒:大多数代码的默认选择仍应是 std::mutex。自旋锁只在线程被钉死在专属核上、且竞争可测量时才值得用;读多写少的场景则应考虑 seqlock。完整的基准代码与原始 perf stat 输出均已公开。这篇实录的价值在于示范了一条可复用的方法路径:每一步优化都用硬件计数器验证因果,而不是凭直觉堆技巧。