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

x86-64环境下伪共享与字节对齐引发的性能异常问题咨询

问题解答

核心原因是x86 CPU默认开启的相邻缓存行硬件预取机制触发了隐性伪共享,导致c被a/b的缓存一致性流量牵连。

缓存行地址计算

x86-64架构CPU的标准缓存行大小为64字节,对第一次测试的变量地址做缓存行对齐计算:

# a/b 所在缓存行范围:0x406200 ~ 0x40623F
0x406200 & ~(64-1) = 0x406200

# c 所在缓存行范围:0x406240 ~ 0x40627F
0x406258 & ~(64-1) = 0x406240

# d 所在缓存行范围:0x406280 ~ 0x4062BF
0x406298 & ~(64-1) = 0x406280

可以看到:a/b的缓存行和c的缓存行是相邻的前后行,d的缓存行和a/b的缓存行间隔了一个完整的64字节缓存行。

性能差异原因

x86 CPU为了提升顺序访问场景的性能,默认开启相邻缓存行预取:当某个缓存行被高频访问时,硬件会自动将它的下一个相邻缓存行预取到访问核心的私有缓存中。
第一次测试的运行流程触发了非预期的缓存一致性流量:

  • thread1、thread2高频修改a/b所在的缓存行,硬件预取器自动将相邻的c所在缓存行预取到运行thread1、thread2的核心缓存中,状态为共享
  • thread3每次修改c时,都需要发送RFO(读所有权)请求,将其他核心中c所在缓存行的状态置为无效,才能获得独占修改权限
  • 这个过程产生了大量不必要的缓存一致性开销,属于预取引入的隐性伪共享,所以thread3的执行速度大幅变慢
  • d的缓存行和a/b的缓存行间隔了64字节,不会被预取逻辑牵连,所以thread4的运行速度符合预期

第二次测试符合预期的原因

将a/b改为int64_t后,变量整体内存布局偏移,a/b所在的缓存行和c所在的缓存行不再是相邻关系,中间至少间隔了一个完整缓存行,预取逻辑不会把c的缓存行预取到运行thread1、thread2的核心中,因此c不会被a/b的伪共享流量牵连,结果符合你的预期。

验证方案

你可以通过以下操作验证上述结论:

  • 关闭CPU的相邻缓存行预取功能后重跑第一次测试,thread3和thread4的耗时会基本一致
  • 把第一次测试中的p1数组长度从7改为15,让c和a/b的缓存行间隔至少128字节,thread3的耗时也会降到和thread4接近

内容的提问来源于stack exchange,提问作者Ryan Gao

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 09:06:05