打印
[AVR单片机]

21频道 iar PK gcc 现场直播ing

[复制链接]
79627|51
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
smartpower|  楼主 | 2007-9-14 12:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
21频道 iar PK gcc 实况转播


2楼testa.c                iar win
iar 44  bytes program
gcc 122 bytes program
gcc 50  bytes program  //-nostartfiles


2楼testb.c                iar win
iar 344  bytes program
gcc 536  bytes program
gcc 464  bytes program  //-nostartfiles

以上两个程序太小,框架代码太大.


20楼浮点数 三角函测试        gcc win
iar 1389 bytes program
gcc 1240 bytes program //-nostartfiles


26楼 马达控制 测试        gcc win
gcc: 1646 bytes program + 295 bytes data
iar: 1661 bytes program + 358 bytes data


34~35楼 遥控测试         iar win
gcc: 3708 bytes program + 169 bytes data
iar: 3076 bytes program + 229 bytes data
39~45楼
gcc: 3510 bytes program + 169 bytes data
iar: 3094 bytes program + 229 bytes data
iar:设置RSTACK = CSTACK = heap = 0后
    3094 bytes program + 165 bytes data





下一个环节你就出题人!!!!

请速速提交你的测试程序吧!! 最好编译后在能2K以上.

相关帖子

沙发
smartpower|  楼主 | 2007-9-14 12:22 | 只看该作者

testa.c testb.c源文件下载

testa.c testb.c源文件下载

https://bbs.21ic.com/upfiles/img/20079/200791820438891.rar

使用特权

评论回复
板凳
dadodo| | 2007-9-14 13:03 | 只看该作者

留个记号

回去试一下

使用特权

评论回复
地板
testcode| | 2007-9-14 13:19 | 只看该作者

把startfiles的关闭看看结果...

试试
CFLAGS += -nostartfiles

testa.c:

Size after:
AVR Memory Usage
----------------
Device: atmega48

Program:      12 bytes (0.3% Full)
(.text + .data + .bootloader)

Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)



-------- end --------

使用特权

评论回复
5
粉丝| | 2007-9-14 13:52 | 只看该作者

对于testa.c ,GCC才用了10条指令!另外的没时间试!

include<avr/io.h>
int main(void)
{
  c6:    cf ef           ldi    r28, 0xFF    ; 255
  c8:    d0 e1           ldi    r29, 0x10    ; 16
  ca:    de bf           out    0x3e, r29    ; 62
  cc:    cd bf           out    0x3d, r28    ; 61

  unsigned int a,b,c;
  unsigned char buf;
  DDRD =0xff;
  ce:    8f ef           ldi    r24, 0xFF    ; 255
  d0:    81 bb           out    0x11, r24    ; 17
  a=100;
  b=200;
  c=300;
  buf=0;
  d2:    80 e0           ldi    r24, 0x00    ; 0
  while(1)
   {
    buf++;
  d4:    8f 5f           subi    r24, 0xFF    ; 255
    PORTD =buf;
  d6:    82 bb           out    0x12, r24    ; 18
  d8:    fd cf           rjmp    .-6          ; 0xd4 <main+0xe>

使用特权

评论回复
6
smartpower|  楼主 | 2007-9-14 14:05 | 只看该作者

---

---去除不用了的代码,找点空间

使用特权

评论回复
7
John_Lee| | 2007-9-14 14:50 | 只看该作者

这不是事实!!

LZ的数据是经过了连接(ld)后的最终执行程序的大小,不能真实地反映“编译器”的水平,LZ的testa.c经过gcc编译所产生的代码只有12字节,下面是dump的代码:
int main ()
{
        unsigned int a,b,c;
        unsigned char buf;
        DDRD = 0xff;
   0:   8f ef           ldi     r24, 0xFF       ; 255
   2:   81 bb           out     0x11, r24       ; 17
        a = 100;
        b = 200;
        c = 300;
        buf = 0;
   4:   80 e0           ldi     r24, 0x00       ; 0
        while (1) {
                buf++;
   6:   8f 5f           subi    r24, 0xFF       ; 255
                PORTD = buf;
   8:   82 bb           out     0x12, r24       ; 18
   a:   00 c0           rjmp    .+0
}

希望LZ提供iar“编译”后的代码,再次PK一下。

什么原因造成了连接后的代码偏大呢?这要归咎于libc,其中的crt(就是所谓的启动代码)占用了相当大的空间。启动代码dump如下:
00000000 <__vectors>:
   0:   19 c0           rjmp    .+50            ; 0x34 <__ctors_end>
   2:   32 c0           rjmp    .+100           ; 0x68 <__bad_interrupt>
   4:   31 c0           rjmp    .+98            ; 0x68 <__bad_interrupt>
   6:   30 c0           rjmp    .+96            ; 0x68 <__bad_interrupt>
   8:   2f c0           rjmp    .+94            ; 0x68 <__bad_interrupt>
   a:   2e c0           rjmp    .+92            ; 0x68 <__bad_interrupt>
   c:   2d c0           rjmp    .+90            ; 0x68 <__bad_interrupt>
   e:   2c c0           rjmp    .+88            ; 0x68 <__bad_interrupt>
  10:   2b c0           rjmp    .+86            ; 0x68 <__bad_interrupt>
  12:   2a c0           rjmp    .+84            ; 0x68 <__bad_interrupt>
  14:   29 c0           rjmp    .+82            ; 0x68 <__bad_interrupt>
  16:   28 c0           rjmp    .+80            ; 0x68 <__bad_interrupt>
  18:   27 c0           rjmp    .+78            ; 0x68 <__bad_interrupt>
  1a:   26 c0           rjmp    .+76            ; 0x68 <__bad_interrupt>
  1c:   25 c0           rjmp    .+74            ; 0x68 <__bad_interrupt>
  1e:   24 c0           rjmp    .+72            ; 0x68 <__bad_interrupt>
  20:   23 c0           rjmp    .+70            ; 0x68 <__bad_interrupt>
  22:   22 c0           rjmp    .+68            ; 0x68 <__bad_interrupt>
  24:   21 c0           rjmp    .+66            ; 0x68 <__bad_interrupt>
  26:   20 c0           rjmp    .+64            ; 0x68 <__bad_interrupt>
  28:   1f c0           rjmp    .+62            ; 0x68 <__bad_interrupt>
  2a:   1e c0           rjmp    .+60            ; 0x68 <__bad_interrupt>
  2c:   1d c0           rjmp    .+58            ; 0x68 <__bad_interrupt>
  2e:   1c c0           rjmp    .+56            ; 0x68 <__bad_interrupt>
  30:   1b c0           rjmp    .+54            ; 0x68 <__bad_interrupt>
  32:   1a c0           rjmp    .+52            ; 0x68 <__bad_interrupt>

00000034 <__ctors_end>:
  34:   11 24           eor     r1, r1
  36:   1f be           out     0x3f, r1        ; 63
  38:   cf ef           ldi     r28, 0xFF       ; 255
  3a:   d2 e0           ldi     r29, 0x02       ; 2
  3c:   de bf           out     0x3e, r29       ; 62
  3e:   cd bf           out     0x3d, r28       ; 61

00000040 <__do_copy_data>:
  40:   11 e0           ldi     r17, 0x01       ; 1
  42:   a0 e0           ldi     r26, 0x00       ; 0
  44:   b1 e0           ldi     r27, 0x01       ; 1
  46:   e6 e7           ldi     r30, 0x76       ; 118
  48:   f0 e0           ldi     r31, 0x00       ; 0
  4a:   02 c0           rjmp    .+4             ; 0x50 <.do_copy_data_start>

0000004c <.do_copy_data_loop>:
  4c:   05 90           lpm     r0, Z+
  4e:   0d 92           st      X+, r0

00000050 <.do_copy_data_start>:
  50:   a0 30           cpi     r26, 0x00       ; 0
  52:   b1 07           cpc     r27, r17
  54:   d9 f7           brne    .-10            ; 0x4c <.do_copy_data_loop>

00000056 <__do_clear_bss>:
  56:   11 e0           ldi     r17, 0x01       ; 1
  58:   a0 e0           ldi     r26, 0x00       ; 0
  5a:   b1 e0           ldi     r27, 0x01       ; 1
  5c:   01 c0           rjmp    .+2             ; 0x60 <.do_clear_bss_start>

0000005e <.do_clear_bss_loop>:
  5e:   1d 92           st      X+, r1

00000060 <.do_clear_bss_start>:
  60:   a0 30           cpi     r26, 0x00       ; 0
  62:   b1 07           cpc     r27, r17
  64:   e1 f7           brne    .-8             ; 0x5e <.do_clear_bss_loop>
  66:   01 c0           rjmp    .+2             ; 0x6a <main>

00000068 <__bad_interrupt>:
  68:   cb cf           rjmp    .-106           ; 0x0 <__heap_end>

大家可以看出,启动代码基本有4个内容:
1、中断向量表
2、设置栈指针
3、复制已初始化数据区
4、清除未初始化数据区

在一个稍大些的,有实用价值的程序中,这4项基本上是都有的,而LZ提供的程序属于比较极端的情况:无中断处理,无已初始化数据,无未初始化数据。在这种情况下,crt中大部分代码属于无用的。我没有用过iar,LZ能不能把用iar生成的程序dump一下,让大家分析分析,或许是iar在连接时发现此等特殊情况而省略了crt中对应部分的代码?如果真是这样,代码应该是如此才对:

crt部分:(省略1、3、4)
   0:   cf ef           ldi     r28, 0xFF       ; 255
   2:   d2 e0           ldi     r29, 0x02       ; 2
   4:   de bf           out     0x3e, r29       ; 62
   6:   cd bf           out     0x3d, r28       ; 61

用户程序部分:
int main ()
{
        unsigned int a,b,c;
        unsigned char buf;
        DDRD = 0xff;
   8:   8f ef           ldi     r24, 0xFF       ; 255
   a:   81 bb           out     0x11, r24       ; 17
        a = 100;
        b = 200;
        c = 300;
        buf = 0;
   c:   80 e0           ldi     r24, 0x00       ; 0
        while (1) {
                buf++;
   e:   8f 5f           subi    r24, 0xFF       ; 255
                PORTD = buf;
  10:   82 bb           out     0x12, r24       ; 18
  12:   00 c0           rjmp    .-6

哈哈,只有20字节!在这个程序中,还有个极端情况:除main外无其它函数!那么连栈设置都可以省略了,最终就剩下12字节。不知iar能否生成此等最优的代码?或者那位再提供一个有中断,有初始化数据和未初始化数据的程序,我们再来PK一下。

使用特权

评论回复
8
smartpower|  楼主 | 2007-9-14 16:02 | 只看该作者

testa.c 在iar上生成的代码

@00000000: _..X_HUGE_HEAP_SIZE
+00000000:   C022        RJMP    PC+0x0023        Relative jump
+00000001:   9518        RETI                     Interrupt return
+00000002:   9518        RETI                     Interrupt return
+00000003:   9518        RETI                     Interrupt return
+00000004:   9518        RETI                     Interrupt return
+00000005:   9518        RETI                     Interrupt return
+00000006:   9518        RETI                     Interrupt return
+00000007:   9518        RETI                     Interrupt return
@00000008: _..X_HEAP_SIZE
+00000008:   9518        RETI                     Interrupt return
+00000009:   9518        RETI                     Interrupt return
+0000000A:   9518        RETI                     Interrupt return
+0000000B:   9518        RETI                     Interrupt return
+0000000C:   9518        RETI                     Interrupt return
+0000000D:   9518        RETI                     Interrupt return
+0000000E:   9518        RETI                     Interrupt return
+0000000F:   9518        RETI                     Interrupt return
@00000010: _..X_RSTACK_SIZE
+00000010:   9518        RETI                     Interrupt return
+00000011:   9518        RETI                     Interrupt return
+00000012:   9518        RETI                     Interrupt return
+00000013:   9518        RETI                     Interrupt return
+00000014:   9518        RETI                     Interrupt return
+00000015:   9518        RETI                     Interrupt return
+00000016:   9518        RETI                     Interrupt return
+00000017:   9518        RETI                     Interrupt return
+00000018:   9518        RETI                     Interrupt return
+00000019:   9518        RETI                     Interrupt return
@0000001A: _..X_FLASH_BASE

///////////////////////////////

---- F:smartpowerworkTRY ry.c -----------------------------------------------------------------
61:           DDRD = 0xff;
+0000001A:   EF0F        SER     R16              Set Register
+0000001B:   B90A        OUT     0x0A,R16         Out to I/O location
65:           buf = 0;
+0000001C:   E000        LDI     R16,0x00         Load immediate
85:               buf++;
+0000001D:   9503        INC     R16              Increment
86:               PORTD = buf;
+0000001E:   B90B        OUT     0x0B,R16         Out to I/O location
+0000001F:   CFFD        RJMP    PC-0x0002        Relative jump

一共6句

//////////////////////////////////////////////////

@00000020: ?C_FUNCALL
---- No Source ------------------------------------------------------------------------------------
+00000020:   0000        NOP                      No operation
@00000021: __exit
+00000021:   9588        SLEEP                    Sleep
+00000022:   CFFE        RJMP    PC-0x0001        Relative jump
@00000023: ?C_STARTUP
+00000023:   E30F        LDI     R16,0x3F         Load immediate
+00000024:   BF0D        OUT     0x3D,R16         Out to I/O location
+00000025:   E001        LDI     R16,0x01         Load immediate
+00000026:   BF0E        OUT     0x3E,R16         Out to I/O location
+00000027:   E2C0        LDI     R28,0x20         Load immediate
+00000028:   E0D1        LDI     R29,0x01         Load immediate
@00000029: ?call_low_level_init
+00000029:   D003        RCALL   PC+0x0004        Relative call subroutine
@0000002A: ?cstartup_call_main
+0000002A:   DFEF        RCALL   PC-0x0010        Relative call subroutine
+0000002B:   DFF4        RCALL   PC-0x000B        Relative call subroutine
+0000002C:   CFF3        RJMP    PC-0x000C        Relative jump
@0000002D: __low_level_init
+0000002D:   E001        LDI     R16,0x01         Load immediate
+0000002E:   9508        RET                      Subroutine return



除去系统代码,main中的几条语句只生成了6句汇编代码。

使用特权

评论回复
9
smartpower|  楼主 | 2007-9-14 16:11 | 只看该作者

与7楼兄弟一样一共6条语句

iar:
EF0F        SER     R16              Set Register
B90A        OUT     0x0A,R16         Out to I/O location
E000        LDI     R16,0x00         Load immediate
9503        INC     R16              Increment
B90B        OUT     0x0B,R16         Out to I/O location
CFFD        RJMP    PC-0x0002        Relative jump


gcc:
8f ef           ldi     r24, 0xFF       ; 255
81 bb           out     0x11, r24       ; 17
80 e0           ldi     r24, 0x00       ; 0
8f 5f           subi    r24, 0xFF       ; 255
82 bb           out     0x12, r24       ; 18
00 c0           rjmp    .-6


在这个环节gcc 和 iar 语句数一样。
期待下一个环节。。。。。
大家一起探讨。~

使用特权

评论回复
10
smartpower|  楼主 | 2007-9-14 16:23 | 只看该作者

---

-----

使用特权

评论回复
11
smartpower|  楼主 | 2007-9-14 21:36 | 只看该作者

testb.c编译和连接


testb.c编译和连接

       编译后    连接后
iar    184           344
gcc      132           536

编译后所生成的汇编代码会大量调用库函数,所以编译后的代码量不能代表总体的编译连接效率.
烧录到mcu中的代码为连接后的代码所以我觉得应该以连接好的代码量来评价编译连接效率.

综上,在testa.c及testb.c的编译连接PK中,我认为是iar胜出.

使用特权

评论回复
12
ayb_ice| | 2007-9-15 07:44 | 只看该作者

IAR毕竟是老牌的嵌入式编译器...

使用特权

评论回复
13
粉丝| | 2007-9-15 13:28 | 只看该作者

这样垃圾贴子双龙竟也加精!俺只见一帮GCC末入门的菜鸟在

不懂就谦虚点!不过俺可没心情点化你们这班连门都找不到的菜鸟!AVR坛子的不愧是商业坛子!佩服!结果都还没出来,就已经加了精,双龙的技术实力可见一斑!你干脆改成IAR坛子算了!这个坛子是你双龙攒助的!钱是你出的,你爱怎么玩就怎么玩!你双龙给人的感觉就是一家不学无术,混饭的AVR推广公司!

使用特权

评论回复
14
wolver| | 2007-9-15 21:29 | 只看该作者

没必有进行下一个环节的PK,因为.....LZ

的PK样本程序太简短,实在不能体现编译器的预测优化和库函数的代码效率。
除非有个500行以上较复杂的代码,比如包含:10个以上的用户自定义函数、5个以上的库函数调用、乘除法、结构应用、全局变量应用、4个以上的硬件资源应用...

使用特权

评论回复
15
janeslee| | 2007-9-15 22:01 | 只看该作者

呵呵 加精不一定要帖子最NB吧

我想 双龙可能见到这段时间非技术的东西太多了,好不容易有这种回归技术探讨的,加个精鼓励一下这种氛围,不要上纲上线嘛

使用特权

评论回复
16
donkey89| | 2007-9-16 08:10 | 只看该作者

smartpower对于c的理解是菜鸟级的,这样的测评只不过是现眼而

向testcode学习了一个软开关,不错,呵呵,虽然很少用到这个.

使用特权

评论回复
17
qjy_dali| | 2007-9-16 10:25 | 只看该作者

双龙加酷也没什么不可以

  当然了,我认为LZ是夸大的成份,或者LZ对于GCC的有些优化特性并不是太了解。这种比较有时候很难做到公平,公正。
  双龙加酷,大家也正好可以来讨论讨论

使用特权

评论回复
18
yewuyi| | 2007-9-16 19:41 | 只看该作者

学习学习加看看热闹

此处热闹,鉴定完毕

使用特权

评论回复
19
yewuyi| | 2007-9-16 19:42 | 只看该作者

管它呢,俺就知道用IAR,GCC没碰过,

想用什么用什么,自己感觉用着爽就行

使用特权

评论回复
20
smartpower|  楼主 | 2007-9-16 21:34 | 只看该作者

浮点数 三角函测试

测试代码如下:
#include <iom48.h>  //for iar
#include <avr/io.h>   //for gcc
#include <math.h>

int main(void)
{
    unsigned long i;
    float x,y,z;
    
    DDRD = 0xff;
    
    while(1)
    {    
        x += 1.7;
        y += 2.29;
        z = sin(x * y);
        
        i += 357;
        i = z * i;
        
        PORTD = i;
    }
}

iar 生成的代码大小为: 1398 bytes
gcc 生成的代码大小为:  3956 bytes
----------这不是GCC的真实水平,GCC可以达到1240bytes,我编译配置有误

具体分析见,21,22,23,24楼




使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

442

帖子

11

粉丝