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

subnormal IEEE 754 floating point numbers support on iOS ARM devices (iPhone 4)(在 iOS ARM 设备 (iPhone 4) 上支持低于标准的 IEEE 754 浮点数)

本文介绍了在 iOS ARM 设备 (iPhone 4) 上支持低于标准的 IEEE 754 浮点数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将应用程序从 Linux x86 移植到 iOS ARM (iPhone 4) 时,我发现浮点运算和小值的行为差异.

64bits 浮点数(双精度) 小于[+/-]2.2250738585072014E-308 在 denormal/denormalized/subnormal 数字a href="http://en.wikipedia.org/wiki/IEEE_754-1985" rel="nofollow noreferrer">IEEE 754-1985/IEEE 754-2008 标准.

在 iPhone 4 上,这样小的数字被视为零 (0),而在 x86 上,次正规数可用于计算.

我在 Apple 的文档中找不到任何关于符合 IEEE-754 标准的解释 float(3) 的 Mac OS X 手册页.

但感谢 Stack Overflow 上的一些答案(flush-to-浮点运算中的零行为,iPhone 上的双精度浮点数a> ),我找到了一些线索.

根据一些搜索,似乎 VFP(或 NEON)数学协处理器沿 ARM 内核使用使用清零 (FTZ) 模式(例如,次正规值在输出处转换为 0)和非正规归零 (DAZ) 模式(例如,次正规值在用作输入参数时转换为 0)以提供快速硬件处理 IEEE 754 计算.

<块引用>
  • 完全符合 IEEE754 与 ARM 支持代码
  • 接近 IEEE754 合规性的快速运行模式(仅限硬件)

关于 FTZ 和 DAZ 的详细解释可以在x87 和 SSE 浮点辅助在 IA-32:清零 (FTZ) 和非正规化零 (DAZ)::p><块引用>

FTZ 和 DAZ 模式都可以处理出现无效浮点数据的情况.处理下溢或异常条件.[...].一个数字的区别由 FTZ 和 DAZ 处理是非常微妙的.FTZ 处理下溢条件,同时DAZ 处理非规范化.当计算结果为不正常的.在这种情况下,FTZ 模式将输出设置为零.DAZ 修复了以下情况denormals 用作输入,作为常量或通过将无效内存读入寄存器.DAZ 模式在计算之前将计算的输入设置为零.自贸区然后可以说处理[输出],而DAZ处理[输入].

Apple 开发者网站上有关 FTZ 的唯一信息似乎在 iOS ABI 函数调用指南:

<块引用>

VFP 状态寄存器 |FPSCR |特别 |函数调用不保留条件代码位 (28-31) 和饱和位 (0-4).异常控制 (8-12)、舍入模式 (22-23) 和 清零 (24) 位只能由影响应用程序状态的特定例程(包括框架 API 函数)修改).短向量长度 (16-18) 和跨度 (20-21) 位在函数进入和退出时必须为零.不得修改所有其他位.

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

注意:我还阅读了 Debian 的 ARM Hard Float Port 和 VFP 比较 页面.

我的问题是:

  • 在哪里可以找到有关跨 iOS 设备处理非正常数字的确切答案?

  • 是否可以在不要求编译器仅生成完整的软件浮点代码的情况下将 iOS 系统设置为提供对次正规数的支持?

谢谢.

解决方案

是否可以在不要求编译器仅生成完整的软件浮点代码的情况下将 iOS 系统设置为提供对次正规数的支持?

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

静态内联 void DisableFZ( ){__asm__ volatile("vmrs r0, fpscr
""bic r0, $(1 <<24)
"vmsr fpscr,r0":::r0");}

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

静态内联 void RestoreFZ( ) {__asm__ volatile("vmrs r0, fpscr
""orr r0, $(1 << 24)
"vmsr fpscr,r0":::r0");}

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

While porting an application from Linux x86 to iOS ARM (iPhone 4), I've discovered a difference in behavior on floating point arithmetics and small values.

64bits floating point numbers (double) smaller than [+/-]2.2250738585072014E-308 are called denormal/denormalized/subnormal numbers in the IEEE 754-1985/IEEE 754-2008 standards.

On iPhone 4, such small numbers are treated as zero (0), while on x86, subnormal numbers can be used for computation.

I wasn't able to find any explanation regarding conformance to IEEE-754 standards on Apple's documentation Mac OS X Manual Page For float(3).

But thanks to some answers on Stack Overflow ( flush-to-zero behavior in floating-point arithmetic , Double vs float on the iPhone ), I have found some clues.

According to some searches, it seems the VFP (or NEON) math coprocessor used along the ARM core is using Flush-To-Zero (FTZ) mode (e.g. subnormal values are converted to 0 at the output) and Denormals-Are-Zero (DAZ) mode (e.g. subnormal values are converted to 0 when used as input parameters) to provide fast hardware handled IEEE 754 computation.

  • Full IEEE754 compliance with ARM support code
  • Run-Fast mode for near IEEE754 compliance (hardware only)

A good explanation on FTZ and DAZ can be found in x87 and SSE Floating Point Assists in IA-32: Flush-To-Zero (FTZ) and Denormals-Are-Zero (DAZ):

FTZ and DAZ modes both handle the cases when invalid floating-point data occurs or is processed with underflow or denormal conditions. [...]. The difference between a number that is handled by FTZ and DAZ is very subtle. FTZ handles underflow conditions while DAZ handles denormals. An underflow condition occurs when a computation results in a denormal. In this case, FTZ mode sets the output to zero. DAZ fixes the cases when denormals are used as input, either as constants or by reading invalid memory into registers. DAZ mode sets the inputs of the calculation to zero before computation. FTZ can then be said to handle [output] while DAZ handles [input].

The only things about FTZ on Apple's developer site seems to be in iOS ABI Function Call Guide :

VFP status register | FPSCR | Special | Condition code bits (28-31) and saturation bits (0-4) are not preserved by function calls. Exception control (8-12), rounding mode (22-23), and flush-to-zero (24) bits should be modified only by specific routines that affect the application state (including framework API functions). Short vector length (16-18) and stride (20-21) bits must be zero on function entry and exit. All other bits must not be modified.

According to ARM1176JZF-S Technical Reference Manual, 18.5 Modes of operation (first iPhone processor), the VFP can be configured to fully support IEEE 754 (sub normal arithmetic), but in this case it will require some software support (trapping into kernel to compute in software).

Note: I have also read Debian's ARM Hard Float Port and VFP comparison pages.

My questions are :

  • Where can one find definitive answers regarding subnormal numbers handling across iOS devices ?

  • Can one set the iOS system to provide support for subnormal number without asking the compiler to produce only full software floating point code ?

Thanks.

解决方案

Can one set the iOS system to provide support for subnormal number without asking the compiler to produce only full software floating point code?

Yes. This can be achieved by setting the FZ bit in the FPSCR to zero:

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

Note that this can cause significant slowdowns in application performance when appreciable quantities of denormal values are encountered. You can (and should) restore the default floating-point state before making calls into any code that does not make an ABI guarantee to work properly in non-default modes:

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

Please file a bug report to request that better documentation be provided for the modes of FP operation in iOS.

这篇关于在 iOS ARM 设备 (iPhone 4) 上支持低于标准的 IEEE 754 浮点数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:在 iOS ARM 设备 (iPhone 4) 上支持低于标准的 IEEE 754 浮点数