这可能是因为两种挥发性变量
a和
b过于接近对方,他们属于在同一高速缓存行; 尽管CPU
A仅读取/写入变量
a,而CPU
B仅读取/写入变量
b,但它们仍通过同一高速缓存行彼此耦合。这些问题称为 虚假共享 。
在您的示例中,我们有两种分配方案:
new Thread new Threadnew Container vsnew Threadnew Thread ....new Container new Container.... new Container
在第一种方案中,两个volatile变量几乎不可能彼此接近。在第二种方案中,几乎可以肯定是这种情况。
CPU缓存不能使用单个单词;相反,它们处理高速缓存行。高速缓存行是连续的内存块,例如64个相邻字节。通常,这很好-
如果CPU访问了某个单元,则很有可能也会访问相邻的单元。除您的示例外,该假设不仅无效,而且有害。
假设
a和
b属于同一缓存行
L。CPU
A更新时
a,它会通知其他
L脏的CPU 。由于B
L也正在缓存,因为它正在工作
b,所以
B必须删除其cached
L。因此,下次
B需要读取时
b,必须重新加载
L,这是昂贵的。
如果
B必须访问主内存以进行重新加载,这将是非常昂贵的,通常速度要慢100倍。
幸运的是,
A并
B可以直接对新值,而无需通过主内存去沟通。但是,这需要花费额外的时间。
为了验证这一理论,您可以在中填充额外的128个字节
Container,以使两个的volatile变量
Container不会落在同一高速缓存行中。那么您应该观察到这两个方案执行大约需要相同的时间。
经验教训:通常,CPU假定相邻变量是相关的。如果我们想要自变量,则最好将它们彼此远离。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)