Cache Line 的理解
越靠近cpu的结构,读取速度越快。首先是寄存器,然后是高速缓存,内存....
想要提高执行效率,可尽可能把数据,留在高速缓存中,减少去内存读取数据。
Cache Line 是 CPU 和主存之间数据传输的最小单位。
Cache Line 常见大小为64字节,会在传输数据的时候,从内存中连续取64字节的数据。
举个例子来加深下印象。
从时间复杂度上来看,两者是一样的。按道理来说,他们的执行时间应该是差不多的。但实际上,却差了好几倍第一第一种方式: Loop time:21ms<br />第二种方式: Loop time:61ms
public static void main(String[] args) {
long[][] arr = new long[1024 * 1024][8];
int sum = 0;
long marked = System.currentTimeMillis();
for (int i = 0; i < 1024 * 1024; i += 1) {
for (int j = 0; j < 8; j++) {
sum += arr[i][j];
}
}
System.out.println("Loop time:" + (System.currentTimeMillis() - marked) + "ms");
sum = 0;
marked = System.currentTimeMillis();
for (int i = 0; i < 8; i += 1) {
for (int j = 0; j < 1024 * 1024; j++) {
sum += arr[j][i];
}
}
System.out.println("Loop time:" + (System.currentTimeMillis() - marked) + "ms");
}
数组内存中的顺序。
arr[0][0] |
---|
arr[0][1] |
arr[0][2] |
arr[0][3] |
arr[0][4] |
arr[0][5] |
arr[0][6] |
arr[0][7] |
arr[1][0] |
arr[1][1] |
arr[1][2] |
arr[1][3] |
arr[1][4] |
arr[1][5] |
arr[1][6] |
arr[1][7] |
… |
<br /> |
第一种遍历方式,即按照内存顺序遍历。
所以,在从内存中读取数据的时候,会读取连续的数据到cpu的缓存中。所以会非常快。
第二种遍历方式,并没按照内存顺序读取,而是跳着读取的。
arr[0][0]
arr[1][0]
arr[2][0]
…
这样访问顺序对于cpu的高速缓存并不友好。 每次加载到 CacheLine的数据只用到了其中一个,导致总是去内存读取数据。
作者:GoFun成都技术中心-何刚