一直对ARM执行一条指令需要多少时间不清楚,现在通过一个测试函数来分析一下
C函数如下
starttime = GetCurrentTicks();
for (i = 0; i < fclk * dwLoop; i++) {
;
}
endtime = GetCurrentTicks();
printf("loop %d using %d ms/n", fclk*dwLoop, endtime - starttime);
使用arm-linux-gcc -Os编译得到的对应的asm代码如下:
33f83bb4: ebfffd09 bl 33f82fe0 <GetCurrentTicks>
33f83bb8: e0020594 mul r2, r4, r5
33f83bbc: e3a03000 mov r3, #0 ; 0x0
33f83bc0: e1a06000 mov r6, r0
33f83bc4: e1530002 cmp r3, r2
33f83bc8: 2a000002 bcs 33f83bd8 <do_looptest+0x68>
33f83bcc: e2833001 add r3, r3, #1 ; 0x1
33f83bd0: e1530002 cmp r3, r2
33f83bd4: 3afffffc bcc 33f83bcc <do_looptest+0x5c>
33f83bd8: ebfffd00 bl 33f82fe0 <GetCurrentTicks>
关键的循环代码就三条指令
33f83bcc: e2833001 add r3, r3, #1 ; 0x1
33f83bd0: e1530002 cmp r3, r2
33f83bd4: 3afffffc bcc 33f83bcc <do_looptest+0x5c>
测试结果如下:ARM运行在400MHz,SDRAM为400/3MHz,fclk=8000, dwLoop=1000的时候,花费的时间为1000ms
相当于执行了80000000次的循环,执行的指令为(add+cmp+bcc)*80000000
另一方面,400MHz的周期为2.5ns,根据ARM指令手册,add cmp为normal data processing指令,周期为1S,bcc需要的周期为
2S+1N。因为CPU开启icache,我认为所有的这些循环指令都在cache中,N S都是2.5ns,这样一个循环的时间应该是4S+1N=5*2.5ns
=12.5ns。这样计算正好能满足1秒80000000的循环。
这里还有一些问题,S N是否可以这样假设? ARM使用流水线,这个在实际中怎么体现?