| 5 | 23693 | 23436 | 74349 | 29796 |
| 6 | 23264 | 23707 | 27005 | 44103 |
| 7 | 28574 | 28979 | 33169 | 58759 |
| 8 | 33155 | 34405 | 39339 | 65182 |
| 9 | 37088 | 37788 | 49863 |156745 |
| 10 | 41543 | 42103 | 58533 |215278 |
| 11 | 47638 | 50329 | 66620 |335603 |
| 12 | 49759 | 51228 | 75087 |305075 |
| 13 | 53938 | 53924 | 77790 |366879 |
| 14 | 58422 | 59565 | 90501 |466368 |
| 15 | 62161 | 64129 | 90814 |525780 |
| 16 | 67061 | 66663 | 98734 |440558 |
| 17 | 71132 | 69753 |171203 |506631 |
| 18 | 74102 | 73130 |293947 |550920 |
我们可以看到,从[9,1024] 以后,时间显注上升。包括[17,512] 和 [18,512] 也显注上升。这是由于,我机器的 L1 Cache 是 32KB, 8 Way 的,前面说过,8 Way 的一个组有 64 个 Cache Line,也就是 4096 个字节,而 1024 个整型正好是 4096 Bytes,所以,一旦过了 8 Way + 4096 Bytes 这个界,每个步长都无法命中 L1 Cache,每次都是 Cache Miss,所以,招致拜访时间一下子就上升了。而 [16, 512]也是一样的,其中的几步末尾招致 L1 Cache 末尾失效。
示例三
接上去,我们再来看个示例。下面是一个二维数组的两种遍历方式,一个逐行遍历,一个是逐列遍历,这两种方式在实际下去说,寻址和计算量都是一样的,执行时间应该也是一样的。
const int row = 1024;
const int col = 512
int matrix[row][col];
//逐行遍历
int sum_row=0;
for(int r=0; r<row; r++) {
for(int c=0; c<col; c++){
sum_row += matrix[r];
}
}
//逐列遍历
int sum_col=0;
for(int c=0; c<col; c++) {
for(int r=0; r<row; r++){
sum_col += matrix[r];
}
}
但是,并不是,在我的机器上,失掉下面的结果。
逐行遍历:0.081ms
逐列遍历:1.069ms
执行时间有十几倍的差距。其中的缘由,就是逐列遍历关于 CPU Cache 的运作方式并不友好,所以,付出庞大的代价。
示例四
(责任编辑:admin)