【false sharing】伪共享
引言
当代计算机存储体系,基本构成磁盘、内存、cpu高速缓存、cpu寄存器。
以cpu为例:
现代cpu都是多核cpu,cpu一般有3级缓存。其中二级缓存是专用的,多核处理器中,每个内核独享L2 cache;三级缓存则是高层级的缓存,它被所有内核共享。
什么是伪共享
伪共享主要发生在L2 cache。内核独享L2,为了保证不同内核L2数据的一致性,缓存机制会强制刷新已更改的L2。
一个数据被修改就会触发L2同步,这很直观,看起来也毫无破绽。不过,考虑到内存块设计,事情就不会这么简单了。内存通常被划分为2的4、8、16等次方KB 或者 MB大小(小批量的读写,可以兼顾吞吐量和实时性)。
一旦触发L2同步,那么整个内存块上的数据都会被强制重载。那些即使不曾发生变化的数据,也会被重载。
案例
1 | struct foo { |
(不同内核,同时执行上面方法)
这里x,y会出现在L2同一内存块,x值一直不变,但是由于y发生改变。sum_a必须不断的从主内存加载x。
ps:
java代码中,一般只关注对并发修改字段的处理(加锁)。就算写到这里,我也还没想好怎么应用到自己的代码中去。if you can do, plealse mail to me. Ths!
ps2:
神奇的解决方法 — 内存块补全。x放入内存后,塞点无用数据,是内存块不能再加载y。
参考: