PIC个人第2步,PIC C18编译器 一些指令的效率分析!

[复制链接]
4061|5
 楼主| Ryanhsiung 发表于 2011-12-29 19:03 | 显示全部楼层 |阅读模式
本帖最后由 Ryanhsiung 于 2011-12-29 19:14 编辑

千万不要写你不知道会怎么编译的语句有位大鸟说过(是谁我不记得了)
上面的话在现在有点不适用了,现在都是快速开发,没有那么多时间让你了解那么多!
  我个人认为:不需要完全了解,但需要了解一部分比较重要的。
  以下是我认为重要的且测试过,给大家分享一下!

说明:
    测试条件:C18编译器(没有开优化)、PIC18的芯片
    以下分析数据都为指令数,指令数少的不一定快!但肯定会减少CODE的大小。
    使用不同版本的编译器可能会有所偏差。
116位运算的赋值
   1、
  1. uint16_t *const Exactitude_buffer = 0x0FCE; //指向THR1L THR1H
  2. Exactitude_buffer =a;

   2、
  1. TMR1L = LS_BYTE(a);
  2. TMR1L = HS_BYTE(a);// 这里也是指针操作

    以下为汇编代码:
     
  1. *Exactitude_buffer = a;
  2. 3654 CE3D MOVFF 0xe3d, 0xfe9
  3. 3656 FFE9 NOP
  4. 3658 CE3E MOVFF 0xe3e, 0xfea
  5. 365A FFEA NOP
  6. 365C CFDE MOVFF 0xfde, 0xfee
  7. 365E FFEE NOP
  8. 3660 CFDD MOVFF 0xfdd, 0xfed
  9. 3662 FFED NOP
  10. TMR1L = LS_BYTE(a); // 这里也是指针操作
  11. 3742 50DF MOVF 0xfdf, W, ACCESS
  12. 3744 6ECE MOVWF 0xfce, ACCESS
  13. TMR1H = HS_BYTE(a);
  14. 3746 0E01 MOVLW 0x1
  15. 3748 50DB MOVF 0xfdb, W, ACCESS
  16. 374A 6ECF MOVWF 0xfcf, ACCESS

     Exactitude_buffer =a 看起来的简单的多了3条语句。
   若使用第一种简化了操作,第二种更快!
    结论:若是16 32位的单片机,第一种速度肯定比第2种高,但在8位的单片机内…..
  1. 优化以下代码:
  2. Us = 0xffff-Us;
  3. Exactitude_buffer = Us;
  4. 1、通过比较我们知道Exactitude_buffer 很慢,我们改成TMR1L = LS_BYTE(Us); TMR1H = HS_BYTE(Us); 代码减少了3个指令。
  5. 2、Us = 0xffff-Us;作用是取余数,所以这里也可以优化一下。
  6. Us =~Us;
  7. 哇,又少了4个指令
  8. 3、我们已经知道了C18不擅长16位运算,那在优化一下Us =~Us;
  9. LS_BYTE(us)= ~LS_BYTE(us);
  10. HS_BYTE(us)= ~HS_BYTE(us);
  11. 但是结果出人意料,代码还是一样长。因为Us =~Us;所以我建议这里还是这么写不要优化了。
  12. 4、已经优化了7个指令了,还能优化吗?答案是肯定的!
  13. 直接8位取反赋值给相应变量。
  14. TMR1L = ~LS_BYTE(us);
  15. TMR1H = ~HS_BYTE(us);
  16. 这个优化是个漂亮的动作一下少了13个指令。

  17. //us =0xffff-us;
  18. //*Exactitude_buffer =us;
  19. TMR1L = ~LS_BYTE(us);
  20. TMR1H = ~HS_BYTE(us);
  21. 优化成下面写法 少了20条语句,若PIC18以4M晶振,执行时间减少了20us.

2、位域与普通变量

   先前有用过51的单片机,位域会比变量运算多2-3条指令。
   考虑新的程序功能比较多,可以放不下,就试一下C18位域,看看会多几条指令。
   结果出乎我的预计,C18的位域比普通变量快!位域3条,变量4条!
  1. if(Baudrate ==1)
  2. 34B8 0101 MOVLB 0x1
  3. 34BA 05F7 DECF 0xf7, W, BANKED
  4. 34BC E101 BNZ 0x34c0
  5. 125: Baudrate =0;
  6. 34BE 6BF7 CLRF 0xf7, BANKED

  7. if(b_RS485_StartRec ==1)
  8. 34B8 010E MOVLB 0xe
  9. 34BA B53C BTFSC 0x3c, 0x2, BANKED
  10. 128: b_RS485_StartRec =0;
  11. 34BC 953C BCF 0x3c, 0x2, BANKED
332位运算
  1. temp32 = (uint32)value*16384 ; //28条语句
  2. temp32 = (uint32)value<<13 ; //31条语句
这里告诉我们左右移不一定比*法高效。


RyanHsiung 2011-12-29原创,转载请说明





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
yewuyi 发表于 2011-12-29 19:06 | 显示全部楼层
俺给放风
 楼主| Ryanhsiung 发表于 2011-12-29 19:15 | 显示全部楼层
本帖最后由 Ryanhsiung 于 2011-12-29 19:28 编辑
俺给放风
yewuyi 发表于 2011-12-29 19:06

哈哈,写完了!
  请大鸟们指点!
用chrome 写出就会像乱码一样!
shizaigaole 发表于 2011-12-29 20:57 | 显示全部楼层
"这里告诉我们左右移不一定比*法高效。",
对这条表示怀疑。

能否贴出汇编代码?
*运算的时候是否,有函数调用语句?
yewuyi 发表于 2011-12-29 21:13 | 显示全部楼层
那个乘法肯定不是那么算指令数量的, 隐含的东西在后面呢
 楼主| Ryanhsiung 发表于 2011-12-30 08:16 | 显示全部楼层
那个乘法肯定不是那么算指令数量的, 隐含的东西在后面呢
yewuyi 发表于 2011-12-29 21:13

我是将汇编对照的,没有CALL GOTO语句,因为太长了没有贴出汇编
  语句短也不一定快啊!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:嵌入式技术专家
简介:道阻且长,行则将至!

64

主题

4653

帖子

14

粉丝
快速回复 在线客服 返回列表 返回顶部