我最近在 32 核 Skylake Intel 处理器上进行了std::atomic::fetch_add
基准测试。std::atomic::compare_exchange_strong
不出所料(从我听说过的有关 fetch_add 的神话中),fetch_add 的可扩展性几乎比 compare_exchange_strong 高一个数量级。看程序的反汇编std::atomic::fetch_add
是用a实现的lock add
,std::atomic::compare_exchange_strong
用lock cmpxchg
(https://godbolt.org/z/qfo4an)实现。
是什么让lock add
英特尔多核处理器的速度如此之快?据我了解,两条指令的缓慢来自缓存线的争用,并且要以顺序一致性执行两条指令,执行的 CPU 必须以独占或修改模式(来自MESI)将这条线拉入它自己的核心。那么处理器如何在内部优化 fetch_add 呢?
这是基准测试代码的简化版本。compare_exchange_strong 基准测试没有 load+CAS 循环,只有 atomic 上的 compare_exchange_strong 输入变量不断随线程和迭代而变化。所以这只是多个 CPU 争用下指令吞吐量的比较。