打印

闲得无聊,看看哪家编译器比较傻.

[复制链接]
4318|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hgjinwei|  楼主 | 2011-2-12 12:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
测试代码:
int hello(int k)
{
    return -k;
}
int main(void)
{
    int i,k;
    i = 10;
    k = -(-(-(-i)));
    hello(k);

    while(1){
        hello(i);
    }
}

编译器:uVsion V4.10 RealView MDK-ARM
优化级别:0
     9: int main(void)
    10: {
    11:         int     i,k;
    12:         
    13:         
    14:         i = 10;
0x080001AA 220A      MOVS     r2,#0x0A
    15:         k = -(-(-(-i)));
0x080001AC 4250      RSBS     r0,r2,#0
0x080001AE 4240      RSBS     r0,r0,#0
0x080001B0 4240      RSBS     r0,r0,#0
0x080001B2 4243      RSBS     r3,r0,#0
    16:         hello(k);
    17:         
0x080001B4 4618      MOV      r0,r3
0x080001B6 F7FFFFF5  BL.W     hello (0x080001A4)
    18:     while(1){
0x080001BA E002      B        0x080001C2
    19:                 hello(i);
0x080001BC 4610      MOV      r0,r2
0x080001BE F7FFFFF1  BL.W     hello (0x080001A4)
0x080001C2 E7FB      B        0x080001BC
编译结果看出,RealView MDK-ARM 优化级别为0时,丫还真的完全按部就班。

优化级别:1
     9: int main(void)
    10: {
    11:         int     i,k;
    12:         
    13:         
    14:         i = 10;
    15:         k = -(-(-(-i)));
0x080001A8 210A      MOVS     r1,#0x0A
    16:         hello(k);
    17:         
    18:     while(1){
0x080001AA 4608      MOV      r0,r1
0x080001AC F7FFFFFA  BL.W     hello (0x080001A4)
    19:                 hello(i);
0x080001B0 4608      MOV      r0,r1
0x080001B2 F7FFFFF7  BL.W     hello (0x080001A4)
    18:     while(1){
0x080001B6 E7FB      B        0x080001B0
这会聪明多了,知道“k = -(-(-(-i)));”等价于“k = i;”,而且还知道对于整个程序,k = -(-(-(-i))); 根本就是一句废话。

优化级别:2
     9: int main(void)
    10: {
    11:         int     i,k;
    12:         
    13:         
    14:         i = 10;
    15:         k = -(-(-(-i)));
    16:         hello(k);
    17:         
    18:     while(1){
0x080001A8 E7FE      B        main (0x080001A8)
不用往下测了,这已经是最优化的了,都直接编译成死循环了,啥也不干。

编译器:IAR Embedded Workbench IDE  EWARM V5.20
优化级别:None
main:
  0000013C  E92D4038  STMDB        SP!, {R3,R4,R5,LR}
i = 10;
  00000140  E3A0000A  MOV          R0, #0xA
  00000144  E1B04000  MOVS         R4, R0
k = -(-(-(-i)));
  00000148  E1B05004  MOVS         R5, R4
hello(k);
  0000014C  E1B00005  MOVS         R0, R5
  00000150  EBFFFFF7  BL           hello                    ; 0x134
  hello(i);
??main_0:
  00000154  E1B00004  MOVS         R0, R4
  00000158  EBFFFFF5  BL           hello                    ; 0x134
  0000015C  EAFFFFFC  B            ??main_0                 ; 0x154
IAR不认可废话,使用冗余指令时可要注意了。

优化级别:Low
main:
  00000164  E92D4010  STMDB        SP!, {R4,LR}
i = 10;
  00000168  E3A0400A  MOV          R4, #0xA
hello(k);
  0000016C  E1B00004  MOVS         R0, R4
  00000170  EBFFFFF9  BL           hello                    ; 0x15C
  hello(i);
??main_0:
  00000174  E1B00004  MOVS         R0, R4
  00000178  EBFFFFF7  BL           hello                    ; 0x15C
  0000017C  EAFFFFFC  B            ??main_0                 ; 0x174
好像没什么实际性的提高,只是优化了 k = -(-(-(-i))); 直接用 i 代替 k .

优化级别:Medium
main:
  00000198  E92D5000  STMDB        SP!, {R12,LR}
hello(k);
  0000019C  E3A0000A  MOV          R0, #0xA
  000001A0  EBFFFFFA  BL           hello                    ; 0x190
  hello(i);
??main_0:
  000001A4  E3A0000A  MOV          R0, #0xA
  000001A8  EBFFFFF8  BL           hello                    ; 0x190
  000001AC  EAFFFFFC  B            ??main_0                 ; 0x1A4
这个,这个,不说了。和Low级别有区别吗?仅仅少用了一个R4。

编译器:IAR Embedded Workbench IDE EW78K V4.60
PS:这个是8位机,处理器为NEC 78K0 - uPD78F0485
优化级别:None
main:
     02C5    B3          PUSH    BC
     02C6    B5          PUSH    DE
i = 10;
     02C7    140A00      MOVW    DE, #0x000A
k = -(-(-(-i)));
     02CA    C4          MOVW    AX, DE
hello(k);
     02CB    9ABD02      CALL    hello                         ; (0x02BD)
  hello(i);
     02CE    C4          MOVW    AX, DE
     02CF    9ABD02      CALL    hello                         ; (0x02BD)
     02D2    FAFA        BR      0x02CE
秉承IAR的一贯作风:不说废话。

优化级别:Low
main:
     02C5    B5          PUSH    DE
i = 10;
     02C6    140A00      MOVW    DE, #0x000A
k = -(-(-(-i)));
     02C9    C4          MOVW    AX, DE
hello(k);
     02CA    9ABD02      CALL    hello                         ; (0x02BD)
  hello(i);
     02CD    C4          MOVW    AX, DE
     02CE    9ABD02      CALL    hello                         ; (0x02BD)
     02D1    FAFA        BR      0x02CD
没啥优化,只是堆栈少用了2字节。

优化级别:Medium
main:
     02C5    100A00      MOVW    AX, #0x000A
     02C8    9ABD02      CALL    hello                         ; (0x02BD)
  hello(i);
     02CB    100A00      MOVW    AX, #0x000A
     02CE    9ABD02      CALL    hello                         ; (0x02BD)
     02D1    FAF8        BR      0x02CB
再少2字节堆栈,看来8位机优化时优先对资源作优化。

结论:
还是 uVsion 比较听话,要她老实时,丫绝无怨言,按部就班,踏踏实实。而一旦让她表现时,她的疯狂总会给你意想不到的刺激。加了优化时调试程序可要注意了,这个编译器只要你给了她权利,她可是很喜欢多管闲事的。
而相比之下,IAR可要自主一点,她有自己的想法,不管你是否愿意。

相关帖子

沙发
hgjinwei|  楼主 | 2011-2-12 13:00 | 只看该作者
测试IAR时忘了选择CPU,使用的是ARM7TDMI,而Keil使用的是STM32F103VC。
不知影响有多大。

使用特权

评论回复
板凳
sdpz| | 2011-2-12 13:45 | 只看该作者
楼主说的很生动啊。:kiss:

使用特权

评论回复
地板
yewuyi| | 2011-2-12 14:26 | 只看该作者
测试IAR时忘了选择CPU,使用的是ARM7TDMI,而Keil使用的是STM32F103VC。
不知影响有多大。
hgjinwei 发表于 2011-2-12 13:00


呵呵,可能影响会很大,也可能基本没影响,所以,测试结论没有意义。

不处于同样条件下测试,测试结论不具备比较的意义。

使用特权

评论回复
5
hgjinwei|  楼主 | 2011-2-12 17:24 | 只看该作者
IAR 处理器改为ARM  Cortex-M3 后测试结果:
优化级别:None

main:
  00000098  B538      PUSH         {R3,R4,R5,LR}
i = 10;
  0000009A  200A      MOVS         R0, #0xA
  0000009C  0004      MOVS         R4, R0
k = -(-(-(-i)));
  0000009E  0025      MOVS         R5, R4
hello(k);
  000000A0  0028      MOVS         R0, R5
  000000A2  F7FFFFF5  BL           hello
  hello(i);
??main_0:
  000000A6  0020      MOVS         R0, R4
  000000A8  F7FFFFF2  BL           hello
  000000AC  E7FB      B            ??main_0

优化级别:Low

main:
  000000B4  B510      PUSH         {R4,LR}
i = 10;
  000000B6  240A      MOVS         R4, #0xA
hello(k);
  000000B8  0020      MOVS         R0, R4
  000000BA  F7FFFFF7  BL           hello
  hello(i);
??main_0:
  000000BE  0020      MOVS         R0, R4
  000000C0  F7FFFFF4  BL           hello
  000000C4  E7FB      B            ??main_0

优化级别:Medium

main:
  000000D0  B580      PUSH         {R7,LR}
hello(k);
  000000D2  200A      MOVS         R0, #0xA
  000000D4  F7FFFFF8  BL           hello
  hello(i);
??main_0:
  000000D8  200A      MOVS         R0, #0xA
  000000DA  F7FFFFF5  BL           hello
  000000DE  E7FB      B            ??main_0


好像差不多,只是指令不同。

使用特权

评论回复
6
airwill| | 2011-2-12 17:34 | 只看该作者
用速度优先测试过吗?
RVMDK 可能还会把 hello  inline 掉呢.

使用特权

评论回复
7
hgjinwei|  楼主 | 2011-2-12 18:37 | 只看该作者
用速度优先测试过吗?
RVMDK 可能还会把 hello  inline 掉呢.
airwill 发表于 2011-2-12 17:34

没有,2级优化时 RVMDK 已经认为所有代码都是废话,直接编译成 B  . 了

使用特权

评论回复
8
Simon21ic| | 2011-2-13 01:03 | 只看该作者
试一下IAR的high优化 + Multi-file compilation + Discard Unused Publics?

使用特权

评论回复
9
123jj| | 2011-2-13 05:00 | 只看该作者
uVsion 对非volatile命名的延时性变量循环体,在深度优化时,当作无效代码处理,直接优化掉。

请将变量定义为volatile属性一试。

使用特权

评论回复
10
hgjinwei|  楼主 | 2011-2-13 10:04 | 只看该作者
uVsion 对非volatile命名的延时性变量循环体,在深度优化时,当作无效代码处理,直接优化掉。

请将变量定义为volatile属性一试。
123jj 发表于 2011-2-13 05:00


volatile属性只适用于全局变量吧,局部变量声明为 volatile 好像没什么实际意义。谁都知道C语言函数之间不能直接互访局部变量,所以也就没有局部变量“挥发”之说。

有循环体的话,uVision 还是不会优化掉的,不管是不是 volatile 。

使用特权

评论回复
11
yhn1973| | 2011-2-13 11:56 | 只看该作者
呵呵,编译器的优化还是太傻了,编程者既然写成k = -(-(-(-i)));肯定有他的用意,否则不会傻到这样写,所以编译器如果碰到太傻的写法,干脆就不优化,因为太傻的写法往往有很深澳的用意。

使用特权

评论回复
12
拿起书本| | 2011-2-13 12:25 | 只看该作者
学习了

使用特权

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

本版积分规则

10

主题

760

帖子

1

粉丝