victzhang 发表于 2010-12-1 01:16:24

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)

dmxfeng 发表于 2010-12-1 07:11:56

记号!

jiaweijing 发表于 2010-12-1 07:26:16

mark

chenerbox 发表于 2010-12-1 07:54:49

以前试着把能在keil下编译的程序移到iar去,折腾了好几天也没有办法正常工作,最后算了,还是用keil了

flyhouse 发表于 2010-12-1 08:14:59

回复【3楼】chenerbox
以前试着把能在keil下编译的程序移到iar去,折腾了好几天也没有办法正常工作,最后算了,还是用keil了
-----------------------------------------------------------------------

t同感,不想折腾了。

takashiki 发表于 2010-12-1 08:54:51

不同意楼主的观点,虽然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,大不了嵌入汇编就是了。

victzhang 发表于 2010-12-1 18:19:24

回复【5楼】takashiki岚月影
-----------------------------------------------------------------------
使用LX51的测试已经加上了。LX51和全局变量着色几乎没太大作用。

对于Dhrystone测试的批评确实很多,因此该测试结果只能做参考。但这至少是一个较大的工程,比较还是有一定意义的,至少要比闪个LED比较有价值得多。
在我手头还有些较大的完整Keil和IAR项目,很想用两个编译器都试一下作个比较。但由于Keil和IAR差异较大,不太好移植,所以也没有试过。如果谁能把一个实际的大型工程移植到两个编译器中试一下,测试结果会更有意义。

其实对于已有的Keil工程代码,也没必要移植到IAR上,太麻烦了,一般项目也不会对代码大小和效率有那么高要求。Keil和IAR我都用过一段时间,感觉编译器区别还是不小的。至于用哪个编译器和IDE,可根据自己的喜好而定。我看过keil和iar生成的汇编代码,各有各的优缺点,差距不是特别大。

因此,8051上,如果已经在用keil了不妨继续用,新项目里有条件的话不妨试试IAR。用过后可根据个人喜好选择用哪一个。

haigerl 发表于 2010-12-1 18:26:16

mark

STM8L103 发表于 2010-12-1 18:38:44

难道 新版本IAR 8051优化有质的提升??

貌似通常情况下,iar8051优化要逊于KEIL C51才是。

june4th 发表于 2010-12-1 18:50:14

我原来测过,用手头的几个项目,各有胜负,Keil胜得多一些。
不过其他单片机编译器,IAR毫无疑问是王者,包括ARM,把“原厂”的Keil打得满脸桃花开。

STM8L103 发表于 2010-12-1 18:58:18

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差。

s3c2440 发表于 2010-12-1 19:32:51

学习一下,我还是初学

zxcao 发表于 2010-12-1 20:17:53

mark

flor 发表于 2010-12-7 09:48:20

IAR没有用过,不知道还可以编译C51.
但是keil的重入功能很不好用,尤其涉及到多任务时.这可能是keil c51的优化特性所致.
非重入函数好象不能调用重入函数?我记不太清楚了.反正多任务系统时keil C51不爽!

alsdjf 发表于 2010-12-7 10:42:30

IAR高优化还是要小心,以前作G729优化的时候试过,打到高,计算结果错误。

alsdjf 发表于 2010-12-7 10:43:36

当然,是IAR for ARM, not for 8051

ghbjimmy 发表于 2010-12-26 23:33:24

正想试一下IAR FOR 8051呢!

shdjdq 发表于 2010-12-27 08:50:15

没有明确结果的比较

lrzxc 发表于 2010-12-27 09:08:06

来看看结果,好像也没弄清楚

lixupeng 发表于 2010-12-29 09:18:36

还没用过IAR 8051有时间试试

Hello_World 发表于 2011-3-5 23:35:42

从51到ARM,我都用的IAR
当年放弃Keil的原因是他不是标准C,移植代码时比较麻烦
相比之下IAR要好很多。
还有一点,也就是楼主所说的编译效率
所以,我决定全套都选IAR,
后来学AVR和ARM的时候,界面都不陌生,且代码移植也比较方便。

很庆幸,我至今还没有后悔!

Hello_World 发表于 2011-3-5 23:41:46

用IAR的不好就是国内使用的人比较少,相关的代码也很少,交流不太方便
所以每次在网上找到资料后,要花一些时间去看,看懂思路后再进行移植或者自己重写

不过,这也不完全算是一件坏事吧!

luoyiming1984 发表于 2011-3-9 01:25:32

记号,IAR 7.60的飘过

millwood0 发表于 2011-3-9 08:26:17

a vote of confidence for Keil, from my cornor of high reliability embedded computing.

ioro55555 发表于 2011-3-9 10:37:00

从来不用优化的飘过~

xiaolei0428 发表于 2011-3-9 21:51:23

mark

Core_i7 发表于 2011-3-25 11:06:41

Mark

yk0yk 发表于 2011-3-30 13:01:04

谢谢楼主的讲解,新手了解中

wufeng212009 发表于 2011-3-30 14:11:54

回复【楼主位】victzhang
-----------------------------------------------------------------------

收藏了。。。

theophilus 发表于 2011-4-15 09:25:38

区别应该在于IAR会inline而Keil不会。。。

fhl2397 发表于 2011-4-25 16:17:52

回复【23楼】luoyiming1984 罗菜鸟
-----------------------------------------------------------------------
你好,我之前用的是IAR FOR NEC,现在换stc单片机了,所以也就换了IAR FOR 51,方便的话留下您的QQ号,请您多多指教

fanmingming 发表于 2011-9-18 09:10:36

回复【楼主位】victzhang
-----------------------------------------------------------------------

IAR的厉害不是吹出来的!!!学AVR的时候比较过了GCC和IAR,觉得IAR很厉害,很严谨!!!看来事实也是如此!

fengyuyuan 发表于 2011-9-18 09:48:35

kankan

louemusic 发表于 2011-9-22 19:54:28

想给楼主说的是,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)

void_main 发表于 2011-9-22 20:24:41

回复【34楼】louemusic
-----------------------------------------------------------------------

我一直在用IAR写msp430的程序,很少写51的程序,所以keil用的比较少,最近做一个项目,给别人写驱动不得不用keil,但是keil的data、idata、xdata和printf很是让我纠结,能否说说keil存储空间的分配和printf怎么关联到指定串口或显示屏

wjshw 发表于 2011-10-9 23:18:21

直接用楼主的代码,软件版本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)

wjshw 发表于 2011-10-9 23:28:28

顺便问一下,谁知道不使用系统的库文件能不能用?当我把库选项配置成“None”时,编译不能通过。
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_683451QPOZ2B.jpg
(原文件名:无标题.jpg)

fengyiyu1006 发表于 2011-10-10 07:00:42

学习了,对于初学的我,现在还只是写一些小的代码,看不出多大差别

lhbzqh 发表于 2011-11-17 11:45:21

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)

766465864 发表于 2012-3-30 09:07:41

唉,作为刚入职不久的人来说,代码的效率简直就是天方夜谭啊,学习学习了

KongQuan 发表于 2012-3-30 15:32:17

用keil C51写的程序,要移植到其他平台时,会麻烦一些。

xiaobenyi 发表于 2012-4-20 09:54:16

这里的讨论,确实是很精彩,我刚好遇到一个公司同事用IAR写的复杂工程,而我习惯用Keil,要转到IAR,新建一个工程好多麻烦事,到现在也没弄出可用的hex来.
可以说,从容易上手这一点来说,keil占优势,呵呵,当初我学用keil的时候几乎没有遇到困难

xunke 发表于 2012-6-19 11:58:33

是不是keil 对数学函数的编译效率比IAR要高?

dyzhenhuai 发表于 2013-10-19 23:00:24

各有优势,努力学习!!!!!

schwarz 发表于 2013-10-19 23:37:59

flor 发表于 2010-12-7 09:48 static/image/common/back.gif
IAR没有用过,不知道还可以编译C51.
但是keil的重入功能很不好用,尤其涉及到多任务时.这可能是keil c51的优 ...

重入问题无解,8位单片机通病,无论keil还是iar缺省都是不可重入的,iar针对其他8位机的编译器都是如此。8位机ram小,缺乏间址指令和间址寄存器,用重入这种标准c语言特征代价太大了。

Gallen.Zhang 发表于 2013-10-19 23:49:02

一直用keil编写C51的飘过

jackee 发表于 2013-10-23 08:46:05

      mark         

eddia2012 发表于 2013-10-25 08:35:34

习惯问题,一直用keil c51

tacbo2012 发表于 2014-2-21 17:49:41

学习了{:lol:}{:lol:}{:lol:}

zhangfuhg 发表于 2014-2-21 19:58:32

一直用keil编写C51{:smile:}。适合我用,习惯了!

xjtyOnly51 发表于 2014-4-11 10:02:49

mark{:smile:}

ppdd 发表于 2014-6-21 19:54:30

关注。 差别大,用了Keil,不想换了。

imliyucai 发表于 2014-6-24 16:23:35

刚学单片机时用8051,是用KEIL。后来搞其他单片机,都是用IAR。感觉IAR好些。

hyf88 发表于 2014-11-20 01:04:06

您好,请教:我用的keil C9。5。1和9.5.3 ,都只看到有9级优化,您的11级优化,在那个版本呢?
谢谢

日日♂夜夜 发表于 2015-4-20 17:10:30

请问 全局寄存器着色是什么意思

mathison 发表于 2017-10-8 16:12:03

本帖最后由 mathison 于 2017-10-8 20:45 编辑

C51中的   _at_在 IAR 中怎样实现的 ?


unsigned char xdata FSCON _at_ 0xFC00;
unsigned char xdata FSCMD_at_ 0xFC01

korren 发表于 2017-10-8 19:38:06

用@代替_at_

mathison 发表于 2017-10-8 21:04:59

本帖最后由 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]
查看完整版本: Keil C51与IAR 8051的编译效率比较!