这次说下局部变量的位宽对于程序的影响。
大家都清楚,局部变量都是在栈中实现的,并且在函数调用结束时释放掉,所以有些人在定义局部变量的位宽时并没有仔细的考虑位宽的影响,随意定义。在一般的情况下,并不会造成很大的影响,但是在循环操作的情况下,就会影响程序的性能。
下面这段程序,用了BIT_U16定义了局部变量i,j。汇编内嵌在C中。
- void LcdInit(void )
- {
- [0xe92d40f8] stmfd r13!,{r3-r7,r14}
- BIT_U16 i, j;
- LcdCtrlInit();
- [0xeb000447] bl LcdCtrlInit
- LcdPowerOnInit();
- [0xeb00033b] bl LcdPowerOnInit
- for (i=0; i<320; i++)
- [0xe3a05000] mov r5,#0
- [0xe59f6568] ldr r6,0x0001655c ; = #0x60090800
- [0xe3a07000] mov r7,#0
- ......
- [0xe2850001] add r0,r5,#1
- [0xe3c05b40] bic r5,r0,#0x10000
- [0xe3550f50] cmp r5,#0x140
- [0x3afffff1] bcc 0x15ff4 ; (LcdInit + 0x18)
- {
- for (j=0; j<240; j++)
- [0xe3a04000] mov r4,#0
- ......
- [0xe2840001] add r0,r4,#1
- [0xe3c04b40] bic r4,r0,#0x10000
- [0xe35400f0] cmp r4,#0xf0
- [0x3afffff6] bcc 0x15ff8 ; (LcdInit + 0x1c)
- {
- LcdMatrix[j][i] = 0x00000000;
- [0xe0840104] add r0,r4,r4,lsl #2
- [0xe0860400] add r0,r6,r0,lsl #8
- [0xe7807105] str r7,[r0,r5,lsl #2]
- LcdSetPara(0x0000);
- [0xe3a00000] mov r0,#0
- [0xeb00044e] bl LcdSetPara
- }
- }
- LcdStartImg();
- [0xe8bd40f8] ldmfd r13!,{r3-r7,r14}
- [0xea000484] b LcdStartImg
- }
可能大家还没有看出来问题所在,再来一段用BIT_U32定义i,j的程序。
- void LcdInit(void )
- {
- [0xe92d40f8] stmfd r13!,{r3-r7,r14}
- BIT_U32 i, j;
- LcdCtrlInit();
- [0xeb000445] bl LcdCtrlInit
- LcdPowerOnInit();
- [0xeb000339] bl LcdPowerOnInit
- for (i=0; i<320; i++) :
- [0xe59f6564] ldr r6,0x00016554 ; = #0x60090800
- [0xe3a05000] mov r5,#0
- [0xe3a07000] mov r7,#0
- ......
- [0xe2855001] add r5,r5,#1
- [0xe3550f50] cmp r5,#0x140
- [0x3afffff3] bcc 0x15ff4 ; (LcdInit + 0x18)
- { l
- for (j=0; j<240; j++)
- [0xe3a04000] mov r4,#0
- ......
- [0xe2844001] add r4,r4,#1
- [0xe35400f0] cmp r4,#0xf0
- [0x3afffff7] bcc 0x15ff8 ; (LcdInit + 0x1c)
- {
- LcdMatrix[j][i] = 0x00000000;
- [0xe0840104] add r0,r4,r4,lsl #2
- [0xe0860400] add r0,r6,r0,lsl #8
- [0xe7807105] str r7,[r0,r5,lsl #2]
- LcdSetPara(0x0000);
- [0xe3a00000] mov r0,#0
- [0xeb00044c] bl LcdSetPara
- }
- }
- LcdStartImg();
- [0xe8bd40f8] ldmfd r13!,{r3-r7,r14}
- [0xea000484] b LcdStartImg
- }
对比下,大家会发现,每次j的小循环就会多一条指令,每次i的大循环也会多一条指令,按照上面程序设定的320次大循环和240次小循环,可以得出 这段程序会多消耗(240*320+320)=77120个指令,如果认为这些指令的执行时间都是单周期的,且预取译码都正常的情况下,会损耗77120 个指令周期。即使时钟跑在了100MHz,也会损耗0.7712ms。
不要小看这0.7712ms,也许你的程序就因为这0.7712ms达不到实时要求,而要提高频率。而局部变量又不会长期占用RAM的空间。所以建议大家在涉及到这些程序的时候,适当采用机器的位宽,会使写出的程序更有效率。