为什么在Android中使用float而不是double不能提高性能?

12

由于所有智能手机(至少是我可以找到规格的那些)都采用32位处理器,因此我想在广泛计算中使用单精度浮点值会比双精度浮点值表现得明显更好。 但是,这似乎并不是情况。

即使我避免类型转换,并在可能的情况下使用FloatMath包,与基于double的方法相比,除了内存使用外,我几乎看不到任何性能提升。

我目前正在开发一个计算密集型的声音分析工具,每秒执行数百万次乘法和加法运算。 因为在32位处理器上进行双精度乘法需要几个时钟周期,而单精度只需要1个,所以我认为类型更改应该是显着的……但它并不是 :-(

这是有什么合理的解释吗? 是否由于Dalvik VM的工作方式造成的,还是其他原因呢?

3个回答

17

典型CPU上的浮点数单元执行所有计算都是双精度(或更高),并简单地四舍五入或转换为最终精度。换句话说,即使是32位CPU也有64位FPU。

许多手机具有包括FPU的CPU,但已禁用FPU以节省电力,导致浮点运算被缓慢仿真(在这种情况下32位浮点数将是一个优势)。

还有一些矢量单元具有32位FPU,导致64位浮点操作需要更长时间。一些SIMD单元(例如执行SSE指令的单元)以相同的时间执行32位和64位操作,因此您可以同时执行两倍的32位操作,但单个32位操作不会比单个64位操作更快。


好的,谢谢,我想这是有道理的。不过我在使用的设备(Nexus One - Quallcom QSD 8250 Snapdragon)上确实找不到有关FPU的规格说明。您知道我可以在哪里找到这类技术信息吗? - Andreass
这通常是错误的(许多现代x86系统使用SSE来执行单精度浮点运算),而且当涉及到手机处理器时更是如此(其中一些甚至不支持双精度,有些可以比双精度快一个数量级地执行单精度运算)。 - Stephen Canon
@Stephen Canon:我所说的是FPUs(很明显OP在使用)。SSE是SIMD单元的一部分(许多ARM和x86 CPU都有这些单元),而模拟显然没有使用FPU。我严格回答了OP的问题,没有写任何关于浮点数运算的一般性内容。 - Gabe
但是在ARM设备上呢?“arm fpu”的第一个搜索结果是https://developer.arm.com/docs/ddi0439/latest/floating-point-unit/about-the-fpu,这篇文章似乎表明FPU是32位的:https://dzone.com/articles/be-aware-floating-point-operations-on-arm-cortex-m。 - Aaron Franke

8
许多Android设备没有浮点协处理器。我目前正在开发一个计算密集型的音频分析工具,每秒要执行数百万次乘加运算。这对于缺少浮点协处理器的Android设备来说是行不通的。将其转移到使用NDK的C/C++中,然后将目标限制为具有浮点协处理器的ARM7。或者,将您的数学计算改为使用定点模式。例如,Google Maps不使用纬度和经度的十进制度数,而是使用微度(10^6倍的度数),以便可以使用定点数学进行计算。

1
六年后它还有效吗? - sandrstar
2
@sandrstar:现在大多数Android设备都有浮点协处理器。话虽如此,我猜“每秒几百万次乘法和加法”仍需要特殊编码(NDK、RenderScript Compute等)。 - CommonsWare
这些FPU中有多少能够支持双精度或更高精度? - Aaron Franke
@AaronFranke:我不知道,抱歉。 - CommonsWare

3

看起来您正在使用 Nexus One,它有一个 Scorpion 核心。

我相信单精度和双精度标量浮点数在 Scorpion 中都是完全流水线化的,因此尽管操作的延迟可能不同,但吞吐量是相同的。

话虽如此,我相信 Scorpion 也有一个 SIMD 单元,可以对浮点数进行操作,但不能对双精度数进行操作。理论上,利用 SIMD 指令编写的针对 NDK 的程序在单精度上可以比双精度快得多,但需要程序员付出大量的努力。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接