伪共享(false share)简介

时间:2021-10-31 20:45:47

现代计算机都带有很多缓存,用于解决CPU极快的计算速度和主存读写速度不匹配的问题。计算机的cache结构大概如下图:

伪共享(false share)简介 其中主存离CPU比较远,读写速度也最慢,三级缓存(L3)比主存稍微快一点,二级缓存(L2)更快,一级缓存(L1)离CPU最近,读写速度也最快。一般CPU读数据都是先从L1读取,如果L1没有数据,则从L2读取,以此类推,直到主存。

cache的最小组成单位是cache line,每一个缓存都是由很多个cache line组成的。每个cache line的大小一般的32字节或者64字节。cache中的数据操作也是以cache line为单位的,也就是一个cache line上的数据会被同时操作。所以问题来了,看左下的图,假设CPU第一个核需要操作a变量,第二个核需要操作b变量,表面上看来a和b是没有任何关系的,但是不幸的是a和b在同一个cache line中,这样假设核心一修改了变量a的值,那么它将会刷新所有跟a相关的缓存的数据,b变量也就会受到牵连(因为他们在同一个cache line,同生共死)。最后导致的结果就是核心二再去缓存读取b变量的时候cache miss了,需要重新到主存加载新数据,无形中也就带来了性能的损失,这就是所谓的false share(伪共享)。

伪共享(false share)简介怎么样避免伪共享呢?一个典型的例子就是lmax disruptor中的缓存行填充技术。假设cache line的大小是64字节,一个cache line能容纳8个long型变量,disruptor中的做法是在long变量的前面和后面分别填充7个long变量,这样就可以避免我们需要的变量和其他变量在同一个cache line,解决伪共享问题。

cache line的存在也是为什么数据存储会比较快的原因,因为数据中的元素在内存中都是在一起的,很多元素也就会在同一个cache line,当加载一个元素的时候,他的相邻的其他元素也会顺便被加载。