Java False Sharing

Background

如果CPU访问的内存数据不在Cache中(一级、二级、三级),这就产生了Cache Line miss问题,此时CPU不得不发出新的加载指令,从内存中获取数据。

Cache主要分为L1、L2 和 L3,如果出现Cache Line Missing,CPU就要从内存中访问数据,这就会产生一个较大的时延,程序性能显著降低。为此我们不得不提高Cache命中率,也就是充分发挥局部性原理。

  • 时间局部性:对于同一数据可能被多次使用,自第一次加载到Cache Line后,后面的访问就可以多次从Cache Line中命中,从而提高读取速度(而不是从下层缓存读取)。
  • 空间局部性:一个Cache Line有64字节块,我们可以充分利用一次加载64字节的空间,把程序后续会访问的数据,一次性全部加载进来,从而提高Cache Line命中率(而不是重新去寻址读取)。

举例,长度为16的row和column数组,在Cache Line 64字节数据块上内存地址是连续的,能被一次加载到Cache Line中,所以在访问数组时,Cache Line命中率高,性能发挥到极致。

1
2
3
4
5
6
7
public int run(int[] row, int[] column) {
int sum = 0;
for(int i = 0; i < 16; i++ ) {
sum += row[i] * column[i];
}
return sum;
}

变量i则体现了时间局部性,i作为计数器被频繁操作,一直存放在寄存器中,每次从寄存器访问,而不是从主存甚至磁盘访问。虽然连续紧凑的内存分配带来高性能,但并不代表它一直都能带来高性能。

https://blog.csdn.net/qq_27680317/article/details/78486220