[size=2]
这种小的数据不会引起操作系统页面调度的,数据大了就有可能。编译后汇编代码是一样的。
5: #define n 4
6: int main()
7: {
0040B750 push ebp
0040B751 mov ebp,esp
0040B753 sub esp,8Ch
0040B759 push ebx
0040B75A push esi
0040B75B push edi
0040B75C lea edi,[ebp-8Ch]
0040B762 mov ecx,23h
0040B767 mov eax,0CCCCCCCCh
0040B76C rep stos dword ptr [edi]
8:
9: int a[n][n];
10: int i,j,k=0;
0040B76E mov dword ptr [ebp-4Ch],0
11:
12: //程序段一,以下称A
13: for(i=0;i
0040B775 mov dword ptr [ebp-44h],0
0040B77C jmp main+37h (0040b787)
0040B77E mov eax,dword ptr [ebp-44h]
0040B781 add eax,1
0040B784 mov dword ptr [ebp-44h],eax
0040B787 cmp dword ptr [ebp-44h],4
0040B78B jge main+6Ch (0040b7bc)
14: for(j=0;j
0040B78D mov dword ptr [ebp-48h],0
0040B794 jmp main+4Fh (0040b79f)
0040B796 mov ecx,dword ptr [ebp-48h]
0040B799 add ecx,1
0040B79C mov dword ptr [ebp-48h],ecx
0040B79F cmp dword ptr [ebp-48h],4
0040B7A3 jge main+6Ah (0040b7ba)
15: a[i][j]=k;
0040B7A5 mov edx,dword ptr [ebp-44h]
0040B7A8 shl edx,4
0040B7AB lea eax,[ebp+edx-40h]
0040B7AF mov ecx,dword ptr [ebp-48h]
0040B7B2 mov edx,dword ptr [ebp-4Ch]
0040B7B5 mov dword ptr [eax+ecx*4],edx
0040B7B8 jmp main+46h (0040b796)
0040B7BA jmp main+2Eh (0040b77e)
16: //程序段二,以下称B
17: for(j=0;j
0040B7BC mov dword ptr [ebp-48h],0
0040B7C3 jmp main+7Eh (0040b7ce)
0040B7C5 mov eax,dword ptr [ebp-48h]
0040B7C8 add eax,1
0040B7CB mov dword ptr [ebp-48h],eax
0040B7CE cmp dword ptr [ebp-48h],4
0040B7D2 jge main+0B3h (0040b803)
18: for(i=0;i
0040B7D4 mov dword ptr [ebp-44h],0
0040B7DB jmp main+96h (0040b7e6)
0040B7DD mov ecx,dword ptr [ebp-44h]
0040B7E0 add ecx,1
0040B7E3 mov dword ptr [ebp-44h],ecx
0040B7E6 cmp dword ptr [ebp-44h],4
0040B7EA jge main+0B1h (0040b801)
19: a[i][j]=k;
0040B7EC mov edx,dword ptr [ebp-44h]
0040B7EF shl edx,4
0040B7F2 lea eax,[ebp+edx-40h]
0040B7F6 mov ecx,dword ptr [ebp-48h]
0040B7F9 mov edx,dword ptr [ebp-4Ch]
0040B7FC mov dword ptr [eax+ecx*4],edx
0040B7FF jmp main+8Dh (0040b7dd)
0040B801 jmp main+75h (0040b7c5)
20:
21: return 0;
0040B803 xor eax,eax
22: }
0040B805 pop edi
0040B806 pop esi
0040B807 pop ebx
0040B808 mov esp,ebp
0040B80A pop ebp
0040B80B ret
连续访问和隔几个访问有什么区别?都是从首地址开始计算偏移的,这一句就是访问mov dword ptr [eax+ecx*4],edx;对于一个4列的二维数组访问a[i][j]都是用a+16*i+4*j进行访问的,意思就是访问每一个元素都要计算一次a+16*i+4*j的值,计算这个值之前你是加了i的值还是加j对这句a+16*i+4*j的计算没有影响,所以在没有缺页中断的情况下这两段代码的执行时间是相同的。至于你说的“程序段B的寻址时间显然是A的两倍多”完全没有道理,你是怎么测算出来的?计算程序运行时间的问题你可以问飞燕,她做oj对这个有经验。测试代码时间要将代码连续运行很多次以减小计时误差,还要保证操作系统负载不变,因为现在的系统都是分时的,时间片轮换调度,所以计时的时候要保证程序的占用cpu时间和等待时间不变。我直接回答你的问题吧:
Q:既然汇编代码是一样的那这两个程序段的执行效果也是一样的咯?
A:寻址代码是一样的,但因为访问次序不同,所以不好说执行效果一样。一个是按行访问,一个是按列,比如说对于a[0][1]这个元素,一个是第二个访问,一个是第五个访问,但是两种方式下计算地址a+16*i+4*j都是一样的,访问时间也是一样的。
[size=2]
Q:可即便是这样的程序段不至于引起页面调度,至少寻址是不同的吧?
A:看汇编就知道寻址是相同的。即使你不懂汇编也应该知道a[i][j]的寻址是a+16*i+4*j来计算地址的。行地址a+16*i加行内偏移4*j。
Q:程序段B的寻址时间显然是A的两倍多呀?
A:显然是你的数据不正确,应该是你的测算方法不对。
补充一点,你对比这两段程序:
1:for(i=0;i
2: for(j=0;j
3: a[i][j]=k;
4:for(j=0;j
5: for(i=0;i
6: a[i][j]=k;
执行时间:1和5相同,2和4相同,所以(1,2)的嵌套和(4,5)的嵌套也相同,3和6不用说也相同。从那里可以看出区别?
不知道永远的极光如何来测试这两个程序段?可否把你的代码贴一下~谢过~
[/size]