打印
[AVR单片机]

GCCAVR 和 CodeVision AVR 编译实测对比

[复制链接]
3188|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
AIRWILL|  楼主 | 2007-1-4 19:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    最近, 经朋友推荐, 得知新版的 CodeVisionAVR 增加了 CodeWizardAVR(
自动生成初始化代码的功能), 又鉴于其超小体积的编译器和集成环境(IDE), 
不禁对其产生了兴趣. 于是对不久前下载到的 CVAVR 试用了一下, 并对其编译
特性和我现在正用的 WinAVR 进行了对比. 

现公布我的对比结果.
 编译器资料:
Keil C51 V8.0   (优化 9级)
WinAVR-20060421 (优化 size )
CodeVisionAVR VERSION 1.25.2 beta1 Standard (Small 最大优化 size)

测试程序介绍: 这是我自己编写的 uart 通信协议
主要有下面几个部分

1. TIMER_ISR(主要完成启动发送和超时错误中止)
KEIL_C51           73   115 bytes
GCCAVR 24a - 30c:  c2   194 bytes
CVAVR  131 - 192:  c2   194 bytes   
/*GCCAVR lst 文件计 byte 地址, 而 CVAVR lst 文件里计word 地址*/
                
2. UART_ISR(通信中断服务)
KEIL_C51          19A   410 bytes 
GCCAVR 30c - 5fc: 2f0   752 bytes
CVAVR  192 - 287: 1EA   490 bytes  

3. PC2   (时钟校正, 监控rxd引脚,保存定时器的值)
GCCAVR  D4 - 170: 9C    156 bytes
CVAVR   5e - 93:  6A    106 bytes          
        
4. CC   (校正判断, 采用四次采样, 去最大最小值, 求平均值的方法)
GCCAVR 170 - 212:  A2   162 bytes
CVAVR   93 - 116: 106   262 bytes     
              
 UART (模块名, 对比总共使用的代码空间)
GCCAVR  A4 - 6CA: 626   1574 bytes
CVAVR   5E - 2CF: 4E2   1250 bytes    
        31E- 3E7: 192   402 bytes   (公共子程序)
CVAVR  编译后的代码总空间: 1652bytes  
(还有几个小函数的编译对比未列出)

    对比的细节和结论说明:        
    CVAVR 能够将未用的死代码优化掉(不编译). 这一点是 gccavr 所没有的.
    
    另外 CVAVR 很喜欢生成大量公共子程序, 让我计算空间挺费劲.
    
    为了节省代码空间, 我使用了 goto. 可是 CVAVR 却不支持 goto! 没有弄
明白为什么, 经过简单处理后, 看编译结果(跳转指令)还能反映对比特性.

    cvavr 在数组和计算方面, 相距甚远; 而中断处理函数的空间, 略有优势, 
这主要得益于采用了模拟栈来保存寄存器, 这样可以调用公共子程序完成寄存器
保存和恢复.但大量的公共子程序对处理效率(速度)是很大影响的. 
 
    最后, 顺便提起一下 gccavr 的一个弱点. 当中断服务调用外部子程序时, 
尽管被调函数仅使用了很少的寄存器, 也会认为该函数改变了所有可变寄存器. 
然而这个弱点在 CVAVR 也同样存在.(Keil C51 通过 ORC 来解决这个问题)

相关帖子

沙发
gtw| | 2007-1-5 12:53 | 只看该作者

问题是

用不同的编译器,对于相同的功能表述,可能有不同的优化方式……
仅仅作这些对比是不够的。
另外,在编译时,一是有效代码尺寸,二是有效代码内容,这两者都是很重要的。

使用特权

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

不优化size

或优化速度再来个对比

使用特权

评论回复
地板
dadodo| | 2007-1-9 14:59 | 只看该作者

没下文了?

使用特权

评论回复
5
erlking| | 2007-1-13 16:21 | 只看该作者

使用goto是个绝对错误的想法

要知道,人家做编译器的可不是白痴,下面这断代码:
if(a==0)
{
b = 1;
func_1();
}
else if(a==1)
{
b=2;
func_1();
}
else if(a==2)
{
b=3;
func_1();
}
else
{
b=4;
}
很明显,这里func_1()重复调用3次,但是最后一个选项中没有调用到,而编译器会把这三次调用的函数整合到一段汇编里去。
所以呢,用C编程只要保持良好的编程风格就行了,关于节省代码量的事,大可以交给编译器去做。

不信年可以将以上的代码用keil C51编译一下试试。

使用特权

评论回复
6
AIRWILL|  楼主 | 2007-2-4 20:45 | 只看该作者

不赞成楼上的说法

虽然, 不无道理. 
楼上的代码过于简单, 不能说明大问题.
keil c 的优化能力并不强. 代码大了, 就大折扣啦

使用特权

评论回复
7
athlon64fx| | 2007-2-4 22:02 | 只看该作者

不仅仅是效率.

在绝多大数情况下可读性比效率更重要.

使用特权

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

本版积分规则

556

主题

17720

帖子

884

粉丝