单线程迁移至其他核心时原子同步如何工作?附Rust/C++代码场景
Relaxed内存序下跨核心缓存同步问题
// Rust/C++ 伪代码(二者内存模型一致) SomeFunc(){ x = counter.load(Ordering::Relaxed) //#1 counter.store(x+1, Ordering::Relaxed) //#2 y = counter.load(Ordering::Relaxed) //#3 }
问题场景
假设SomeFunc由某线程执行,在#2与#3操作之间线程被中断,#3操作在另一核心执行。请解答:
- 在此无显式release/acquire的场景下,counter变量能否同步核心1的最新更新值?
- 线程短暂休眠后迁移至其他核心时,会加载整个缓存行及线程本地存储?
解答
- 针对第一个问题:能同步到核心1的最新更新值。虽然用的是Relaxed内存序,但线程自身的存储操作(#2)对后续自身的加载操作(#3)受"线程内顺序"规则约束——不管线程是否跨核心执行,这个规则都生效。也就是说,#3的Relaxed load一定能看到#2的Relaxed store的结果,哪怕#3在另一个核心执行。
- 针对第二个问题:线程迁移到新核心时,会加载对应变量所在的缓存行,但不会主动加载整个线程本地存储。缓存系统以缓存行为单位运作,当新核心需要访问counter变量时,若本地缓存无对应缓存行,会通过缓存一致性协议(如MESI)从原核心或主存拉取包含counter的整个缓存行。而线程本地存储(TLS)中的内容,只有当线程在新核心上实际访问时才会被加载到该核心缓存,不会一次性全部加载。
内容的提问来源于stack exchange,提问作者Rohit Sharma
相关产品推荐
相关产品推荐

