a[i][j]与a[j][i]性能差别的原因

来源:互联网 发布:centos 加载驱动 编辑:程序博客网 时间:2024/05/24 03:03
 
     一下内容仅是个人理解,有错误之处,望大家谅解和指正。

a[i][j]使用时间:94s

for( k = 0 ; k <10000 ; k++ )
for( i = 0 ; i<MAX; i++ )
for( j = 0;j < MAX; j++ )
a[i][j] = 0;
a[j][i]使用时间:488s

for( k = 0 ; k <  10000  ; k++ )
for( i = 0 ; i<MAX; i++ )
for( j = 0;j < MAX; j++ )
a[j][i] = 0;
我将两种方法使用gcc生成了汇编代码。使用diff比较只发现了一下四句汇编代码的不同
1c1
<  .file"array.c"
---
>  .file"array1.c"
31c31
<  movl4194352(%esp), %eax
---
>  movl4194356(%esp), %eax
33c33
<  addl  4194356(%esp), %eax
---
>  addl        4194352(%esp), %eax
并且,这四句汇编在这行的时候不会产生性能差别,那性能差别出现在那里。可定不是循环、计算数据产生的差别。差别会出现在内存的访问位置上吗?不会的,内存是随机访问,访问任何一个位置内存的地址的时间应该是一样的。我们现在考虑一下是不是操作系统的缓存的功能。首先,本程序在加载到内存执行、以后除了cpu访问内存之外没有任何的资源消耗。所以说不是系统的问题。想了很久,想到cpu访问数据的时候是以块进行访问的,将取来的数据放到缓存中。因为a[i][i]是顺序访问,所以cpu缓存中的数据可以直接使用,无需再访问内存。而a[j][i]非顺序访问,下一个访问的位置,不在cpu的缓存中。

提议:在写代码的时候
1. 对数组、结构体进行顺序访问。提高缓存的命中率。
2. 减少不必要的判断,提高cpu的分支预测的命中率

3. 避免数据页访问,避免频繁的缺页。

原创粉丝点击