在Microsoft配置测试中询问了以下问题。我无法弄清楚哪一个会更好。有人可以帮帮我吗?
代码1:
int MAX=1000;
int a[MAX][MAX];
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++)
a[j][i]=i*j;
代码2:
int MAX=1000;
int a[MAX][MAX];
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++)
a[i][j]=i*j;
哪个是对的?
答案 0 :(得分:3)
假设您使用的是C / C ++,代码2可能会更快。 C / C ++以行主顺序存储数组,这意味着最右边维度的变化给出了内存地址的最小变化。由于这一点,CPU缓存可以帮助代码的性能,你不必担心页面错误(代码2以单调的顺序访问内存地址,所以一旦程序完成读取其中一个包含数据的页面,它将不再需要查看该页面。)
答案 1 :(得分:2)
区别在于他们如何访问内存。你的阵列布局如下:
row 0 - 1000 integers
row 1 - 1000 integers
etc.
现在,您的第一个循环访问a[0][0]
,然后访问a[1][0]
等。所以它将找到第0行,然后找到第0列,并更新它。然后它必须找到第1行,找到该行中的第0列,然后访问它。所以你最终会在整个地方访问内存 - 基本上是随机的。这对CPU缓存有害,因为它必须在每次内存访问时重新加载。
你的第二个循环访问a[0][0]
,然后a[0][1]
,然后访问a[0][2]
等。所以它找到第0行,然后按顺序访问列。这对于处理器缓存来说是 good ,并且执行速度更快,因为它不需要经常重新加载。