Keil C51与IAR 8051的编译效率比较!
一直听说IAR编译效率很高,今天就用Keil和IAR同时编译了dhrystones测试程序测试了一下效率~这里使用的C51和IAR C/C++ Compiler for 8051都是目前(2010.11)我能找到的最新版。
关于Dhrystone测试的简短介绍可见http://baike.baidu.com/view/1885614.htm
Keil uVision V4.10, C51 Compiler V9.02
使用9级代码体积优化
Program Size: data=15.1 xdata=5523 code=5179
182 dhrystones/second
使用9级代码速度优化
Program Size: data=15.1 xdata=5523 code=5313
189 dhrystones/second
使用8级代码速度优化
Program Size: data=15.1 xdata=5523 const=0 code=5597
198 dhrystones/second
使用8级代码速度优化,LX51链接
Program Size: data=15.1 xdata=5523 const=0 code=5594
198 dhrystones/second
使用11级代码速度优化,LX51链接
Program Size: data=15.1 xdata=5523 const=0 code=5594
198 dhrystones/second
http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_601618PO4XVJ.png
Keil C51编译效率测试
IAR Embedded Workbench, IAR C/C++ Compiler for 8051 7.60.1 (7.60.1.40026)
代码体积优化(最高)
4 962 bytes of CODE memory
25 bytes of DATA memory (+ 7 absolute )
5 704 bytes of XDATA memory
64 bytes of IDATA memory
8 bitsof BIT memory
211 dhrystones/second
代码速度优化(最高)
4 733 bytes of CODE memory
25 bytes of DATA memory (+ 7 absolute )
5 704 bytes of XDATA memory
64 bytes of IDATA memory
8 bitsof BIT memory
255 dhrystones/second
http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_601487IA5B58.png
IAR C/C++ Compiler for 8051编译效率测试
为了保证测试的公平性,在测试时使用了统一的第三方仿真软件Raisonance 8051 Simulator来仿真。先用keil和IAR编译出hex文件,然后一起放到Simulator里去仿真。仿真时使用AT89S51,12MHz晶振。
IAR在编译时printf库大小选择为medium。
看来在该测试中IAR的代码优化确实做得很恐怖的,无论是代码大小和速度都要比keil C51更胜一筹~
更神奇的是在这个测试中代码速度优化生成的代码比体积优化还小!仔细检查了输出的raw-binary格式文件,确实是速度优化时更小!
在使用Keil的实验中发现,在本测试程序中,8级优化和11级优化,使用BL51或LX51,在速度上都没有区别。使用lx51做链接器的优点就是能省3个字节。
另外,在本测试程序中,无论开启还是关闭全局寄存器着色对代码速度和性能都没有影响。
使用9级优化(Common Block Subroutines)会减慢程序运行的速度(189 dhrystones/second),甚至比8级优化时还慢。不过可以缩小些代码体积,这点经验大家可以借鉴下。
顺便附上个IAR EW8051 V7.60 完全光盘Full正式版下载链接(感谢formula555):
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4131100&bbs_page_no=1&bbs_id=9999
测试程序见附件,大家也可以自己试一下。
点击此处下载 ourdev_601488JZZ3L4.rar(文件大小:192K) (原文件名:dhrystone.rar) 记号! mark 以前试着把能在keil下编译的程序移到iar去,折腾了好几天也没有办法正常工作,最后算了,还是用keil了 回复【3楼】chenerbox
以前试着把能在keil下编译的程序移到iar去,折腾了好几天也没有办法正常工作,最后算了,还是用keil了
-----------------------------------------------------------------------
t同感,不想折腾了。 不同意楼主的观点,虽然IAR可能比Keil有优势。
我也用楼主的程序试了一下,Keil,11级优化,全局变量着色,尽可能使用AJMP/ACALL。
我不明白为什么楼主只用9级优化,为了表现Keil很差?还是不知道Keil可以使用LX51来代替L51?
针对代码优化:
Program Size: data=15.1 xdata=5523 const=0 code=5176
creating hex file from "Dhry"...
"Dhry" - 0 Error(s), 17 Warning(s).
Now running 200 Dhrystones...
Dhrystone(1.1) time for 200 passes = 127
This machine benchmarks at 196 dhrystones/second
针对速度优化:
Program Size: data=15.1 xdata=5523 const=0 code=5594
creating hex file from "Dhry"...
"Dhry" - 0 Error(s), 17 Warning(s).
Now running 200 Dhrystones...
Dhrystone(1.1) time for 200 passes = 127
This machine benchmarks at 196 dhrystones/second
很显然,Keil的速度优化,实在是有点-_-!!不是189dhrystones/second了哟。
然后是程序:
从这个就可以看出来,
typedef int boolean;
dhrystones测试程序根本就不是给8位机用的,尤其不是给8051用的。8051中的仅有的一点优势都丧失了,为什么就不能定义为typedef bit boolean;呢。8位机比较MIPS,32位比较DMIPS,你这样比较没有多大的意义。在8051上,Keil不尽人意的地方很多,废物代码很多,但是与IAR 8051相差也不是想象中的远。
因此,8051上,不想折腾IAR,大不了嵌入汇编就是了。 回复【5楼】takashiki岚月影
-----------------------------------------------------------------------
使用LX51的测试已经加上了。LX51和全局变量着色几乎没太大作用。
对于Dhrystone测试的批评确实很多,因此该测试结果只能做参考。但这至少是一个较大的工程,比较还是有一定意义的,至少要比闪个LED比较有价值得多。
在我手头还有些较大的完整Keil和IAR项目,很想用两个编译器都试一下作个比较。但由于Keil和IAR差异较大,不太好移植,所以也没有试过。如果谁能把一个实际的大型工程移植到两个编译器中试一下,测试结果会更有意义。
其实对于已有的Keil工程代码,也没必要移植到IAR上,太麻烦了,一般项目也不会对代码大小和效率有那么高要求。Keil和IAR我都用过一段时间,感觉编译器区别还是不小的。至于用哪个编译器和IDE,可根据自己的喜好而定。我看过keil和iar生成的汇编代码,各有各的优缺点,差距不是特别大。
因此,8051上,如果已经在用keil了不妨继续用,新项目里有条件的话不妨试试IAR。用过后可根据个人喜好选择用哪一个。 mark 难道 新版本IAR 8051优化有质的提升??
貌似通常情况下,iar8051优化要逊于KEIL C51才是。 我原来测过,用手头的几个项目,各有胜负,Keil胜得多一些。
不过其他单片机编译器,IAR毫无疑问是王者,包括ARM,把“原厂”的Keil打得满脸桃花开。 KEIL与IAR移植是有点麻烦。
最主要是指针,KEIL 的指针如果没有存储修饰符,则是通用指针。
IAR指针没有没有存储修饰符,是指向RAM的的指针,通用指针则要加上__generic关键字。
还有就是const处理不一样。
keil 的常量地址没有const属性,可以任意传递。
而IAR常量地址是一个const指针,不能传递给非const指针。
还有位变量问题。KEIL用bit,而iar则用_Bool。
函数重入上,KEIL与IAR也不一样。
IAR还是用了虚拟寄存器。
个人对IAR8051更熟悉一些。
总的来说,IAR更符合标准C一些,而且还支持大部分C99标准语法,
不过IAR8051的效率并不高,应该要比KEIL差。 学习一下,我还是初学 mark IAR没有用过,不知道还可以编译C51.
但是keil的重入功能很不好用,尤其涉及到多任务时.这可能是keil c51的优化特性所致.
非重入函数好象不能调用重入函数?我记不太清楚了.反正多任务系统时keil C51不爽! IAR高优化还是要小心,以前作G729优化的时候试过,打到高,计算结果错误。 当然,是IAR for ARM, not for 8051 正想试一下IAR FOR 8051呢! 没有明确结果的比较 来看看结果,好像也没弄清楚 还没用过IAR 8051有时间试试 从51到ARM,我都用的IAR
当年放弃Keil的原因是他不是标准C,移植代码时比较麻烦
相比之下IAR要好很多。
还有一点,也就是楼主所说的编译效率
所以,我决定全套都选IAR,
后来学AVR和ARM的时候,界面都不陌生,且代码移植也比较方便。
很庆幸,我至今还没有后悔! 用IAR的不好就是国内使用的人比较少,相关的代码也很少,交流不太方便
所以每次在网上找到资料后,要花一些时间去看,看懂思路后再进行移植或者自己重写
不过,这也不完全算是一件坏事吧! 记号,IAR 7.60的飘过 a vote of confidence for Keil, from my cornor of high reliability embedded computing. 从来不用优化的飘过~ mark Mark 谢谢楼主的讲解,新手了解中 回复【楼主位】victzhang
-----------------------------------------------------------------------
收藏了。。。 区别应该在于IAR会inline而Keil不会。。。 回复【23楼】luoyiming1984 罗菜鸟
-----------------------------------------------------------------------
你好,我之前用的是IAR FOR NEC,现在换stc单片机了,所以也就换了IAR FOR 51,方便的话留下您的QQ号,请您多多指教 回复【楼主位】victzhang
-----------------------------------------------------------------------
IAR的厉害不是吹出来的!!!学AVR的时候比较过了GCC和IAR,觉得IAR很厉害,很严谨!!!看来事实也是如此! kankan 想给楼主说的是,KEIL 有data idata xdata内存位置声明,而IAR不需要声明. 上面的测试程序,完全没有使用KEIL的内存声明,这样将会牺牲极大的性能.本来只需要一个字节的指针,现在却要用三个字节来处理,编译出来的能不大吗? IAR上面代码更小,因为内存声明的问题,完全是抽机巧胜.
看看下面用KEIL编译出来的,程序语句没经过任何改动,只是对指针增加了 存储类声明而已.把人该做的事完全交给机器,怎么可能.
生成 代码 .4808字节.
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_678655NR855M.jpg
(原文件名:未命名.jpg)
付程序,要优化的请继续.
点击此处下载 ourdev_6865616PG.rar(文件大小:96K) (原文件名:DHRY_KEIL.rar) 回复【34楼】louemusic
-----------------------------------------------------------------------
我一直在用IAR写msp430的程序,很少写51的程序,所以keil用的比较少,最近做一个项目,给别人写驱动不得不用keil,但是keil的data、idata、xdata和printf很是让我纠结,能否说说keil存储空间的分配和printf怎么关联到指定串口或显示屏 直接用楼主的代码,软件版本iar for 8051 V8.10.1
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_683448YAU4YI.JPG
(原文件名:捕获.JPG)
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_683449NT612J.JPG
(原文件名:捕获2.JPG) 顺便问一下,谁知道不使用系统的库文件能不能用?当我把库选项配置成“None”时,编译不能通过。
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_683451QPOZ2B.jpg
(原文件名:无标题.jpg) 学习了,对于初学的我,现在还只是写一些小的代码,看不出多大差别 IAR 51 比 keil 51 差远了。
我对比了IAR 51、 keil 51、 SDCC 51 的数学函数的编译结果。
代码很简单,如下:
//-----------------------------------------------------------------------------
#include<math.h>
//-----------------------------------------------------------------------------
#if defined SDCC /* for SDCC */
#define DATA__data
__sfr __at(0x80)P0;
__sfr __at(0x90)P1;
__sfr __at(0x99)SBUF0;
#elif defined __C51__ /* for keil C51 */
#define DATAdata
sfr P0 = 0x80;
sfr P1 = 0x90;
sfr SBUF0 = 0x99;
#elif defined __ICC8051__ /* for iar 8051 */
#define DATA __data
__sfr __no_init volatile unsigned char P0 @ 0x80;
__sfr __no_init volatile unsigned char P1 @ 0x90;
__sfr __no_init volatile unsigned char SBUF0 @ 0x99;
#endif
//-----------------------------------------------------------------------------
DATA float var1 = 10.23;
DATA float var2 = 2.56;
DATA float var3 = 1.234;
//-----------------------------------------------------------------------------
void main( void )
{
P0 = (unsigned char)(var1 * var2);
P1 = (unsigned char)(var1 / var2);
#if defined SDCC /* for SDCC */
SBUF0 = (unsigned char)(expf(var3));
#elif defined __C51__ /* for keil C51 */
SBUF0 = (unsigned char)(exp(var3));
#elif defined __ICC8051__ /* for iar 8051 */
SBUF0 = (unsigned char)(exp(var3));
#endif
while(1);
}
编译结果差很远:
SDCC3.0 + Silicon Laboratories IDE4.20
sdcc.exe -c --opt-code-size --no-xinit-opt --iram-size 256 --xram-size 512 --code-size 0x1DFE --debug --use-stdout -V main.c
sdcc.exe --opt-code-size --no-xinit-opt --iram-size 256 --xram-size 512 --code-size 0x1DFE --debug --use-stdout -V main.rel
flash size: 1568 bytes
data ram size: 33 bytes
//////////////////////////////////////////////////////////////////////////////////////////////////
IAR7.50A
3 052 bytes of CODEmemory
65 bytes of DATAmemory (+ 3 absolute )
//////////////////////////////////////////////////////////////////////////////////////////////////
Keil C51 V8.18
flash size: 1366 bytes
data ram size: 21 bytes
//////////////////////////////////////////////////////////////////////////////////////////////////
附上工程:IAR、KEIL、SDCC 51的编译效率比较ourdev_696038LUX52N.rar(文件大小:51K) (原文件名:compare.rar) 唉,作为刚入职不久的人来说,代码的效率简直就是天方夜谭啊,学习学习了 用keil C51写的程序,要移植到其他平台时,会麻烦一些。
这里的讨论,确实是很精彩,我刚好遇到一个公司同事用IAR写的复杂工程,而我习惯用Keil,要转到IAR,新建一个工程好多麻烦事,到现在也没弄出可用的hex来.
可以说,从容易上手这一点来说,keil占优势,呵呵,当初我学用keil的时候几乎没有遇到困难 是不是keil 对数学函数的编译效率比IAR要高? 各有优势,努力学习!!!!! flor 发表于 2010-12-7 09:48 static/image/common/back.gif
IAR没有用过,不知道还可以编译C51.
但是keil的重入功能很不好用,尤其涉及到多任务时.这可能是keil c51的优 ...
重入问题无解,8位单片机通病,无论keil还是iar缺省都是不可重入的,iar针对其他8位机的编译器都是如此。8位机ram小,缺乏间址指令和间址寄存器,用重入这种标准c语言特征代价太大了。 一直用keil编写C51的飘过 mark 习惯问题,一直用keil c51
学习了{:lol:}{:lol:}{:lol:} 一直用keil编写C51{:smile:}。适合我用,习惯了! mark{:smile:} 关注。 差别大,用了Keil,不想换了。 刚学单片机时用8051,是用KEIL。后来搞其他单片机,都是用IAR。感觉IAR好些。 您好,请教:我用的keil C9。5。1和9.5.3 ,都只看到有9级优化,您的11级优化,在那个版本呢?
谢谢 请问 全局寄存器着色是什么意思 本帖最后由 mathison 于 2017-10-8 20:45 编辑
C51中的 _at_在 IAR 中怎样实现的 ?
unsigned char xdata FSCON _at_ 0xFC00;
unsigned char xdata FSCMD_at_ 0xFC01 用@代替_at_ 本帖最后由 mathison 于 2017-10-8 21:08 编辑
korren 发表于 2017-10-8 19:38
用@代替_at_
你是对的,
对于扩展特殊功能寄存器(0xFC00-0xFC08) 不能用 __sfr
FSCON fc00H ------00 ---- ---- ---- ---- ---- ---- IFEN BOOT
FSCMD fc01H -----000 ---- ---- ---- ---- ---- COMD.2 COMD.1 COMD.0
FSDAT fc02H 00000000 FSDAT.7 FSDAT.6 FSDAT.5 FSDAT.4 FSDAT.3 FSDAT.2 FSDAT.1 FSDAT.0
LOCK fc03H ----0000 ---- ---- ---- ---- ILKF DLKF PLKF FLKF
PADRD fc04H --000000 ---- ---- PADRD.5 PADRD.4 PADRD.3 PADRD.2 PADRD.1 PADRD.0
XADRL fc05H 00000000 XADR.7 XADR.6 XADR.5 XADR.4 XADR.3 XADR.2 XADR.1 XADR.0
XADRH fc06H -0000000 ---- XADR.14 XADR.13 XADR.12 XADR.11 XADR.10 XADR.9 XADR.8
YPADR fc07H 00000000 YADR.7 YADR.6 YADR.5 YADR.4 YADR.3 YADR.2 YADR.1 YADR.0
YADRH fc08H -0000000 ---- YADR.14 YADR.13 YADR.12 YADR.11 YADR.10 YADR.9 YADR.8
只能
__no_init __xdata volatile unsigned char FSCON @0xFC00;
__no_init __xdata volatile unsigned char FSCMD @0xFC01;
__no_init __xdata volatile unsigned char FSDAT @0xFC02;
__no_init __xdata volatile unsigned char LOCK @0xFC03;
__no_init __xdata volatile unsigned char PADRD @0xFC04;
__no_init __xdata volatile unsigned char XADRL @0xFC05;
__no_init __xdata volatile unsigned char XADRH @0xFC06;
__no_init __xdata volatile unsigned char YADRL @0xFC07;
__no_init __xdata volatile unsigned char YADRH @0xFC08;
__no_init __xdata volatile unsigned char PADRM @0xFC0F;
页:
[1]