这些二维arrays中的哪一个有利于使用,为什么?

在facebook小组中,我看到了一个类似的问题:

如果一行在下面的二维数组中占主导地位,哪一个是有利的,为什么呢?

a) for(i=0;i<1000;i++) for(j=0;j<1000;j++) temp=temp+a[i][j]; b) for(j=0;j<1000;j++) for(i=0;i<1000;i++) temp=temp+a[i][j] 

从我的观点来看,我可以看出上述两个陈述没有区别。 我想这些都是一样的。

如果我错了,请纠正我?

理论上没有区别。

实际的优点是缓存局部性。 如果访问距离较远的位置,则会增加缓存未命中数,从而导致代码运行速度变慢。

根据您的处理器高速缓存大小,您可能需要用一些相当大的数字替换1000以便感知效果。

Variant(a)更好,因为它比(b)更加缓存友好:您访问连续元素,因此缓存未命中次数较少。 但是,一些编译器可以重新排列循环,因此在编译时,两个变体可能会生成相同的机器代码。

除了性能之外,这两种变体之间没有区别,即产生相同的输出。

然而,很可能是情有可原的情况。 例如,如果数字既是正数又是负数,那么它们可能存在模式,使得一个顺序会导致溢出(或浮点时精度损失),而另一个顺序会表现得更好。

当CPU想要从内存中读取数据/代码时,数据块或从内存移动到缓存。 缓存比RAM快得多,而且要贵得多,所以你几乎没有。 这背后的想法是,通常当你阅读内存的一部分时,你可能会读到与它相近的其他部分。

在方法a中,您逐行读取数组,因此保留了位置。 也就是说,在从行开始的第一次读取时,该行被加载到缓存中,并且该行的其余部分从缓存中读取(缓存命中),因此您具有高缓存命中率,这是好的。

在方法b中,您故意以不连续的方式访问数组,因此您会获得大量缓存未命中,并且您需要始终保持对内存的读取。

据我说,正确的一个是’A’:因为当我们使用2-D数组时,很容易评估元素逐行缓存,而不是逐列,因为缓存用于快速评估,如果更多命中它行为快,所以第一个是正确的,Thanx有一个美好的一天。