iOS ARM设备(iPhone 4)支持低于标准IEEE 754浮点数

在从Linux x86移植到iOS ARM(iPhone 4)的应用程序时,我发现浮点算术和小值的行为有所不同。

64位浮点数(double)小于[+/-] 2.2250738585072014E-308在IEEE 754-1985 / IEEE 754-2008标准中被称为非正规/非正规化/次正常数。

在iPhone 4上,这样的小数字被视为零(0),而在x86上,可以使用次正数来进行计算。

我无法find任何有关苹果Mac OS X手册页上的IEEE-754标准符合性的解释(3) 。

但是,由于堆栈溢出( 在浮点algorithm中的清零行为, iPhone上的Double vs float )的一些答案,我find了一些线索。

根据一些search,似乎沿着ARM内核使用的VFP (或NEON )math协处理器使用了Flush-To-Zero(FTZ)模式(例如,在输出端将低于正常值的值转换为0)和Denormals-Are-Zero DAZ)模式(例如,当用作input参数时,将低于正常值的值转换为0)来提供快速处理IEEE 754计算的硬件。

  • 完整的IEEE754符合ARM支持代码
  • 符合IEEE754标准的运行快速模式(仅限硬件)

关于FTZ和DAZ的一个很好的解释可以在IA-32的x87和SSE浮点协助中find:同花顺零(FTZ)和非正规零(DAZ) :

FTZ和DAZ模式既处理发生无效浮点数据的情况,也处理下溢或非正常情况。 […]。 由保税区和DAZ处理的数量之间的差异非常微妙。 FTZ处理下溢情况,而DAZ处理非正常情况。 计算结果为非正常时,会发生下溢情况。 在这种情况下,FTZ模式将输出设置为零。 DAZ修正了非规范化被用作input的情况,既可以是常量,也可以是将无效内存读入寄存器。 DAZ模式在计算之前将计算的input设置为零。 然后可以说FTZ处理[输出],而DAZ处理[input]。

苹果开发者网站上关于FTZ的唯一的东西似乎在iOS ABI函数调用指南 :

VFP状态寄存器| FPSCR | 特殊| 条件码位(28-31)和饱和位(0-4)不被函数调用保存。 exception控制(8-12),舍入模式(22-23)和清零(24)位只能由影响应用程序状态(包括框架API函数)的特定例程修改。 在函数入口和出口处,短向量长度(16-18)和步长(20-21)位必须为零。 所有其他位不能被修改。

根据ARM1176JZF-S技术参考手册,18.5操作模式 (第一个iPhone处理器),VFP可以被configuration为完全支持IEEE 754(亚正常算术),但在这种情况下,需要一些软件支持(陷入内核以软件计算)。

注意:我也读过Debian的ARM Hard Float Port和VFP比较页面。

我的问题是:

  • 哪里可以find有关跨iOS设备的低于正常数字处理的明确答案?

  • 是否可以设置iOS系统提供对低于正常数量的支持,而不要求编译器只生成完整的软件浮点代码?

谢谢。

是否可以设置iOS系统提供对低于正常数量的支持,而不要求编译器只生成完整的软件浮点代码?

是。 这可以通过将FPSCR中的FZ位设置为零来实现:

static inline void DisableFZ( ) { __asm__ volatile("vmrs r0, fpscr\n" "bic r0, $(1 << 24)\n" "vmsr fpscr, r0" : : : "r0"); } 

请注意,当遇到大量非标准值时,这可能会导致应用程序性能显着下降。 您可以(也应该)在调用任何不能使ABI保证在非默认模式下正常工作的代码之前恢复默认的浮点状态:

 static inline void RestoreFZ( ) { __asm__ volatile("vmrs r0, fpscr\n" "orr r0, $(1 << 24)\n" "vmsr fpscr, r0" : : : "r0"); } 

请提交错误报告 ,请求为iOS中的FP操作模式提供更好的文档。

 •Where can one find definitive answers regarding subnormal numbers 

处理iOS设备?

你已经find了你的答案。 预计ARM不具备相同的浮点function。

•能否让iOS系统提供对低于正常数字的支持,而不要求编译器只生成完整的软件浮点代码?

我不相信,至less我希望如此,以相同的价值获得不同的数字。