2.4.5.Float 与 Double¶
在没有 FPU64 硬件支持的 C2000 器件上,当为 EABI 编译的应用程序对 double 类型执行操作时,会产生很大的开销。
在 EABI 中,double 类型映射为 64 位双精度浮点数。如需了解详情,请参阅应用程序二进制接口 (ABI)。为 EABI (--abi=eabi
) 编译的应用程序可以通过以下方式引入双精度浮点运算:
显式使用
double
类型。除非应用程序需要额外的精度/范围,否则避免使用double
类型。通过浮点常量隐式使用。当常量可以被视为单精度浮点常量时,使用
f
后缀。不带
f
后缀的浮点常量被编译器视为双精度类型。这种行为是由 C 标准规定的。这可能会导致在应用程序中意外引入双精度运算。表 2.10 说明了这种低效率 - 该常量被视为双精度,导致x
从 float 转换为双精度类型。乘法是双精度运算,结果被转换回单精度类型。¶ 常量(被视为 double) 带 f
后缀的常量(被视为 float)floatfoo1(floatx){returnx*42.2;}
floatfoo2(floatx){returnx*42.2f;}
¶ 以双精度执行的运算 以单精度执行的运算 ||foo1||: ADDB SP,#8 MOVZ AR4,SP SUBB XAR4,#8 MOVZ AR6,AR4 LCR #||__c28xabi_ftod|| ; call occurs [#||__c28xabi_ftod||] MOVZ AR4,SP MOVZ AR6,SP MOVL XAR5,#$C$FL1 SUBB XAR4,#8 SUBB XAR6,#4 MOVZ AR4,AR4 MOVZ AR6,AR6 LCR #||__c28xabi_mpyd|| ; call occurs [#||__c28xabi_mpyd||] MOVZ AR4,SP SUBB XAR4,#4 MOVZ AR4,AR4 LCR #||__c28xabi_dtof|| ; call occurs [#||__c28xabi_dtof||] SUBB SP,#8 LRETR ; return occurs
||foo2||: MOVIZ R1H,#16936 MOVXI R1H,#52429 MPYF32 R0H,R1H,R0H LRETR ; return occurs
C 标准库中的数学例程,例如
sqrt
。在 COFF 中,float
和double
都是 32 位单精度,因此sqrt
和sqrtf
之间没有差异。但是,使用 EABI 时,sqrtf
采用float
参数,sqrt
采用double
。
检测双精度运算
编译器选项--float_operations_allowed=32
可用于检测应用程序是否无意中使用了双精度运算。
此选项可限制应用程序中允许的浮点运算类型。默认为 all。如果设置为 none、32 或 64,则检查应用程序是否将在运行时执行运算。例如,如果在命令行上指定了 --float_operations_allowed=32
,则在应用程序包含双精度运算时编译器会发出错误消息。有关详细信息,请参阅 TMS320C28x 优化 C/C++ 编译器用户指南。