You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

两段近似的C++多线程代码运行耗时差异巨大的原因探究

问题原因分析

两段代码的性能差异核心在于**伪共享(False Sharing)**以及全局变量的内存访问冲突:

第一段代码的性能瓶颈

第一段中,evenSum和oddSum是全局变量,在内存中会被连续分配(全局变量存放在数据段,地址连续)。由于unsigned long long占8字节,而CPU缓存行通常为64字节,这两个变量必然处于同一个缓存行中。

当两个线程分别对这两个变量进行写入操作时,CPU的缓存一致性协议(如MESI)会触发频繁的缓存行失效与同步:

  • 线程修改evenSum时,会标记对应缓存行为"已修改",其他CPU核心中对应的缓存行会被置为"无效"
  • 另一个线程修改oddSum时,发现自己的缓存行已无效,必须等待对方的缓存行同步回主存后重新加载,反之亦然

这种循环往复的缓存同步导致两个线程无法真正并行执行,而是在互相等待缓存更新,最终性能和单线程几乎无异。

第二段代码的优化逻辑

第二段代码中,每个线程先将全局变量的值读取到线程私有局部变量(函数内的evenSum和oddSum是栈上变量,属于线程私有内存),循环中仅对局部变量进行写入操作。

局部变量会被加载到各自CPU核心的独立缓存行中,互相之间不会产生缓存冲突:

  • 两个线程的缓存操作完全独立,不会触发缓存一致性同步
  • 线程可以真正并行执行循环计算,因此耗时接近第一段的一半,达到多线程并行的预期效果

由于你未开启编译优化,编译器不会自动将全局变量的访问优化为局部变量访问,因此这种手动修改的性能提升效果会非常明显。


内容的提问来源于stack exchange,提问作者programmer of c

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 00:50:21