打印
[AVR单片机]

21频道 iar PK gcc 现场直播ing

[复制链接]
楼主: smartpower
手机看帖
扫描二维码
随时随地手机跟帖
21
testcode| | 2007-9-17 00:33 | 只看该作者 回帖奖励 |倒序浏览

验证结果...

gcc 生成的代码大小为:  1312 bytes

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

Program:    1312 bytes (32.0% Full)
(.text + .data + .bootloader)

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



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

使用特权

评论回复
22
smartpower|  楼主 | 2007-9-17 09:30 | 只看该作者

请看看我所使用编译选项那里有问题

以下是我编译时使用的选项,不知道是那里错,还请使用gcc的网友给指正一下.谢谢.我是在avr studio里调默认的make编译的.

avr-gcc.exe  -mmcu=atmega48 -Wall -gdwarf-2                 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT testfloat.o -MF dep/testfloat.o.d  -c  ../../testfloat.c
avr-gcc.exe -mmcu=atmega48 -nostartfiles -Wl,-Map=testb.map testfloat.o     -o testb.elf
avr-objcopy -O ihex -R .eeprom  testb.elf testb.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex testb.elf testb.eep || exit 0
AVR Memory Usage
----------------
Device: atmega48
Program:    3956 bytes (96.6% Full)
(.text + .data + .bootloader)
Data:          8 bytes (1.6% Full)
(.data + .bss + .noinit)

使用特权

评论回复
23
smartpower|  楼主 | 2007-9-17 09:46 | 只看该作者

找到非具体原因了

使用avr studio内的默认的make编译就出现23楼我所说的情况,便使用Mfile所生成的makefile来编译就只有1312bytes,去掉startfiles后就只有1240bytes了,


但不知道是为什么.还请熟悉gcc的朋友给指正一下.

还请testcode朋友给大家分析一下,为什么会这样.以便以后更多的人能了解GCC的特性.


在这个testfloat上我认为还是GCC编译做的更好iar生成的代码1398bytes是gcc生成的代码1240bytes的113%.
看来iar的广告用语会不会有点问题?



gcc 在这个环节胜出.

到底谁强谁弱我们将一起见证,并让更多的网友一起来见证.
希望能有更多的环节,让大家真正的看到两者的实力而不是没事在网上口水战,我们只拿数据说话.

下一个环节那位朋友来提供一个程序?要大一点的哦.小的看不出来因为iar和gcc都有自己的框架,程序小了都是框架的代码,没有办法比较的..........




使用特权

评论回复
24
zsmbj| | 2007-9-17 11:20 | 只看该作者

在工程选项里的优化选择-0s试试。你肯定选了不优化吧。

不优化还比较啥。

使用特权

评论回复
25
wolver| | 2007-9-17 13:08 | 只看该作者

我觉得这个PK越来越有意思了,但就不知双龙的脸色....

会不会越来越难看。哦,说笑话呢,人家大老总怎么会和我们这些小虾米一般见识。

在上一个环节(详见20~24楼)我们把iar PK调了,winavr下gcc编译工具的库代码效率略微领先iar。这一节,我们来PK编译器的预测优化功能。

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

请大家使用连接指向的这个源代码,代码中使用了gcc的一个技术:即用static inline来修饰函数。作用是:如果编译器认为函数在被调用的过程中,可以展开函数体代码,就将函数体代码展开,而不作为函数(或调用地址)......
我不知道iar中是否有这钟类似的修饰说明功能,请用iar的朋友根据上述意思做必要的修改。

测试一:不使用static inline 功能(下载文件中的Makefil默认就是这个设置),测试编译器效率。
编译结果如下:
Size after:
AVR Memory Usage
----------------
Device: atmega8

Program:    1960 bytes (23.9% Full)
(.text + .data + .bootloader)

Data:        295 bytes (28.8% Full)
(.data + .bss + .noinit)

测试二:使用static inline功能,测试编译器预测优化。你需要修改Makefile文件第169行,把该行加"#"号注释调,结果如下:
Size after:
AVR Memory Usage
----------------
Device: atmega8

Program:    1668 bytes (20.4% Full)
(.text + .data + .bootloader)

Data:        295 bytes (28.8% Full)
(.data + .bss + .noinit)

细心的朋友你也许注意到:为什么用static inline功能把函数体代码展开后,编译字节反而小了?!这个问题留给你们慢慢去"烟酒"一下,因为它不属于本次PK讨论的问题,我只是想告诉大家:想要减小代码尺寸有多种办法,换不同类型的编译器是成本最高、最不智的方法....

使用特权

评论回复
26
smartpower|  楼主 | 2007-9-17 15:23 | 只看该作者

回复26楼

你所提供的程序需要作大量的修改才能在iar上运行.

希望你能直接提供gcc版和iar版,只有程序的作者才能保证两个版本的一致性.

使用特权

评论回复
27
wolver| | 2007-9-17 17:02 | 只看该作者

re:27楼

我提供的那个源代码就是在WinAVR-20070525下编译运行的。
我不会用iar,所以不知道要怎么改才能让iar能编译通过.....抱歉!只有等iar和gcc都比较熟悉的朋友啦...

使用特权

评论回复
28
宇宙飞船| | 2007-9-17 17:06 | 只看该作者

楼主的第一条测试GCC才用了6条指令14字节,共:82字节

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

Program:      82 bytes (2.0% Full)
(.text + .data + .bootloader)

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

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

> Process Exit Code: 
> Time Taken: 00:05
*******************************************
00000000 <__vectors>:  //这段代码50字节必需:
   0:    28 c0           rjmp    .+80         ; 0x52 <__data_load_end>
   2:    20 c0           rjmp    .+64         ; 0x44 <__bad_interrupt>
   4:    1f c0           rjmp    .+62         ; 0x44 <__bad_interrupt>
   6:    1e c0           rjmp    .+60         ; 0x44 <__bad_interrupt>
   8:    1d c0           rjmp    .+58         ; 0x44 <__bad_interrupt>
   a:    1c c0           rjmp    .+56         ; 0x44 <__bad_interrupt>
   c:    1b c0           rjmp    .+54         ; 0x44 <__bad_interrupt>
   e:    1a c0           rjmp    .+52         ; 0x44 <__bad_interrupt>
  10:    19 c0           rjmp    .+50         ; 0x44 <__bad_interrupt>
  12:    18 c0           rjmp    .+48         ; 0x44 <__bad_interrupt>
  14:    17 c0           rjmp    .+46         ; 0x44 <__bad_interrupt>
  16:    16 c0           rjmp    .+44         ; 0x44 <__bad_interrupt>
  18:    15 c0           rjmp    .+42         ; 0x44 <__bad_interrupt>
  1a:    14 c0           rjmp    .+40         ; 0x44 <__bad_interrupt>
  1c:    13 c0           rjmp    .+38         ; 0x44 <__bad_interrupt>
  1e:    12 c0           rjmp    .+36         ; 0x44 <__bad_interrupt>
  20:    11 c0           rjmp    .+34         ; 0x44 <__bad_interrupt>
  22:    10 c0           rjmp    .+32         ; 0x44 <__bad_interrupt>
  24:    0f c0           rjmp    .+30         ; 0x44 <__bad_interrupt>
  26:    0e c0           rjmp    .+28         ; 0x44 <__bad_interrupt>
  28:    0d c0           rjmp    .+26         ; 0x44 <__bad_interrupt>
  2a:    0c c0           rjmp    .+24         ; 0x44 <__bad_interrupt>
  2c:    0b c0           rjmp    .+22         ; 0x44 <__bad_interrupt>
  2e:    0a c0           rjmp    .+20         ; 0x44 <__bad_interrupt>
  30:    09 c0           rjmp    .+18         ; 0x44 <__bad_interrupt>
  32:    08 c0           rjmp    .+16         ; 0x44 <__bad_interrupt>

00000034 <__ctors_end>:   //初始化STACK这段代码必需
  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
  40:    02 d0           rcall    .+4          ; 0x46 <main>
  42:    07 c0           rjmp    .+14         ; 0x52 <__data_load_end>
*********************************************************
00000044 <__bad_interrupt>: //出错处理,重新启动。
  44:    dd cf           rjmp    .-70         ; 0x0 <__heap_end>
//****************************以上68个字节必不可少************
00000046 <main>:
{

  unsigned int a,b,c;
  unsigned char buf;
  DDRD =0xff;
  46:    8f ef           ldi    r24, 0xFF    ; 255
  48:    8a b9           out    0x0a, r24    ; 10
  4a:    80 e0           ldi    r24, 0x00    ; 0
  a=100;
  b=200;
  c=300;
  buf=0;
  while(1)
   {
    buf++;
  4c:    8f 5f           subi    r24, 0xFF    ; 255
    PORTD =buf;
  4e:    8b b9           out    0x0b, r24    ; 11
  50:    fd cf           rjmp    .-6          ; 0x4c <main+0x6>
Disassembly of section .fini0:

00000052 <__stop_program>:
  52:    ff cf           rjmp    .-2          ; 0x52 <__data_load_end>

使用特权

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

re:27楼,

不如你把iar下不能编译通过的"宏"列各清单,也许大家可以把26楼的程序重新整理,让两种编译器都可以编译....

使用特权

评论回复
30
smartpower|  楼主 | 2007-9-17 18:49 | 只看该作者

对26楼文件的编译

更改成iar格式后的文件如下:https://bbs.21ic.com/upfiles/img/20079/2007917183347904.rar
去除了watchdog因为两者没有对应的函数.
所以将去除后的函数重新编译了一下,统计数据如下:

gcc: 1646 bytes program + 295 bytes data
iar: 1661 bytes program + 358 bytes data

看来又是gcc胜出,而且在data有使用上胜得很漂亮.

有没有iar的高手或才双龙的高手把这个文件重新给编译一下?
gcc已经赶超iar了.

使用特权

评论回复
31
wolver| | 2007-9-17 20:01 | 只看该作者

re: 31楼

基础不错嘛!这么短时间就修改出iar的编译文件了,非常感谢你的整理工作。不过你提供的源文件忘了把GCC编译用的Makefile文件放进去了....


gcc: 1646 bytes program + 295 bytes data
iar: 1661 bytes program + 358 bytes data

从你提供的数据看,GCC这一轮在编译预测优化上又胜出了,而且对RAM的分配使用上更胜IAR一筹!

使用特权

评论回复
32
wolver| | 2007-9-17 20:59 | 只看该作者

再来个大点的测试程序.....

以下联结的源码
https://bbs.21ic.com/upfiles/img/20079/2007917205040760.rar

GCC的编译结果如下:

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

Program:    3864 bytes (47.2% Full)
(.text + .data + .bootloader)

Data:        169 bytes (16.5% Full)
(.data + .bss + .noinit)

还是麻烦smartpower朋友把GCC与IAR不共通的部分(比如:watchdog)砍了,“宏”部分也改改....然后把改完的源码和编译对比结果传上来....
相关链接:https://bbs.21ic.com/upfiles/img/20079/2007917205040760.rar

使用特权

评论回复
33
smartpower|  楼主 | 2007-9-17 22:43 | 只看该作者

回33楼

修改后的iar 及 gcc文档如下:

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

比分为:
gcc: 3708 bytes program + 169 bytes data
iar: 3076 bytes program + 229 bytes data

这次的分该给谁呢?
相关链接:https://bbs.21ic.com/upfiles/img/20079/200791722407615.rar

使用特权

评论回复
34
wolver| | 2007-9-17 23:20 | 只看该作者

re: 34楼

该谁赢,就谁赢....我推荐个判定:

按33楼的手持机控制代码,经34楼修改为GCC和IAR都可编译的文件,PK结果如下:
这一环节的PK中,IAR代码优化胜出,RAM分配管理方面GCC胜出....

备注:如果有哪位朋友对34楼的源码编译处新的结果,也可重新判定...

使用特权

评论回复
35
smartpower|  楼主 | 2007-9-18 08:34 | 只看该作者

iar gcc 不能通用的地方

1 . 中断函数的书写形式不一样。可以更改。
2 . 宏的话可以自己定义。可以更改。
3 . 延时函数不一样,不可修改。建议pk的代码中最好不要有延时函数。
4 . dog的函数不一样,不可修改。建议pk的代码中最好不要有dog函数。
5 . 对flash,eeprom的操用函数不一样,不方便更改。



当然以上的几点在移植时都可以实现,只是代码大变不具备PK的公平性。

使用特权

评论回复
36
wolver| | 2007-9-18 09:38 | 只看该作者

请smartpower再麻烦一次....

将34楼的源代码中除main()和中断的以外的函数及其声明都加上static inline修饰,再将改好的源码和编译对比结果告知。

我觉得IAR用了种牺牲RAM换函数进出堆栈代码的优化方法,现在将函数用static inline修饰后,函数体被展开,就没有堆栈的保护操作。

使用特权

评论回复
37
zhiwei| | 2007-9-18 12:01 | 只看该作者

对于频繁使用的

寄存器使用全局寄存器变量,IAR支持,代码会一下子减小很多。

使用特权

评论回复
38
wolver| | 2007-9-18 22:06 | 只看该作者

现在把34楼提供的文件....

的函数加ststic inline修饰了,我用GCC编译结果如下:
Size after:
AVR Memory Usage
----------------
Device: atmega8

Program:    3510 bytes (42.8% Full)
(.text + .data + .bootloader)

Data:        169 bytes (16.5% Full)
(.data + .bss + .noinit)

哪位用IAR的朋友把联结的文件编译下,报个结果....谢谢!
相关链接:https://bbs.21ic.com/upfiles/img/20079/200791822559812.rar

使用特权

评论回复
39
smartpower|  楼主 | 2007-9-18 22:21 | 只看该作者

回39楼

39楼的文件编译后结果如下:

3094 bytes of CODE memory
229 bytes of DATA memory

使用特权

评论回复
40
wolver| | 2007-9-18 23:48 | 只看该作者

re: 40楼

哦,根据39楼和40楼的编译结果来看:针对AVR的编译,目前IAR在代码优化(尤其精减代码)方面确实比GCC有独到之处!

但我不明白IAR为什么凭空比GCC多占用大约25%的RAM...因为GCC的汇报结果真实的反映了程序全局变量使用的RAM大小,而IAR多占25%的RAM拿去干嘛用了呢?我对这个现象比较好奇,不知道是否有IAR的高手能现身说法....期待!

声明:以上阐述(包括但不限于:主贴下本人所有的回贴,以及提供的参考测试代码)为个人观点,纯属技术讨论。如被引用于商业领域,需征得本人同意!

使用特权

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

本版积分规则