Chinaunix首页 | 论坛 | 博客
  • 博客访问: 12490
  • 博文数量: 8
  • 博客积分: 187
  • 博客等级: 入伍新兵
  • 技术积分: 80
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-16 09:53
文章分类
文章存档

2012年(8)

我的朋友
最近访客

分类: LINUX

2012-07-11 14:59:39

把局部变量从char或者short类型转换成int类型,可以改善性能并减小代码尺寸,其实,这种转换函数类型参数也有同样的效果,看下面的例子,将216位的值相加,其他第2个数先减半,然后返回一个16位的和:

Short add-v1short ashort b

{

    Return a +b>>1 );

}

虽然这个函数只是一个简单的算术运算,但是对于观察编译器碰到的问题是一个很好的例子,输入值ab和返回值都存放在32位的ARM寄存器中,编译器是否应该考虑这些32位数值在short类型的范围之间呢?或者编译器是否应该通过对低16位数据进行符号位扩展,充填32位寄存器,强制把数值限制在上述范围之间呢?编译器必须把调用者和被调用者作出一致的决策,不是调用者,就是被调用者,必须把数据转换为short类型。

如果参数可以不缩小到定义的数据类型范围,那么称这种函数参数传递是宽的,反之,则称为窄的。观察add-v1的汇编输出结果,就可以知道编译器所来用的是那种形式,如果编译器传递参数是宽的。那么被调用者就必须把参数缩小到正确的用的是哪种形式。如果编译器传递参数是窄的。那么调用者必须缩小参数范围。如果编译器返回值是窄的。那么被调用者就必须在返回前缩小回值的范围。

 对于ADSarmcc来说,函数参数传递和返回值都是窄的。换句话说,调用者要处理调用参数,而被调用者要处理返回值,编译器采用函数的ANSI原型来决定函数参数的数据类型。

函数add-v1armcc下的输出结果显示,编译器把返回值的类型转换为short类型的范围之内,这就说明参数传递和返回值都是窄的。

 Add-v1

   Add   r0r0r1ASR #1    r0=(int)a+((int) b>>1)

   MOV   r0r0LSL #16     

   MOV   r0r0ASR #16       r0=short r0

   MOV   pcr14               return r0

Gcc编译器更为谨慎,对参数值的范围不作任何假设,这个版本的编译器,在调用者和被调用者中将输入参数缩小到short类型的数据范围,同时也都将返回值转换为short类型,下面是add-v1gcc编译后的代码:

 Add-v1-gcc

 MOV  r0r0LSL #16

MOV  r1r1LSL #16

MOV  r1r1LSL #17                r1=(int)b>>1

ADD  r1r1r0,ASR #16             r1+=inta

MOV  r1r1LSL #16

MOV  r0r1ASR #16                r0shortr1

MOV  pc1r                         return r0

尽管宽和窄的函数调用规则各有其优点,但是char或者short类型的函数参数和返回值都会产生额外的开销,导致性能的下降,并增加了代码尺寸。所以,即使是传输一个8位的数据,函数参数和返回值使用int类型也会更有效。

源地址: 

阅读(373) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~