我想知道如何将智能手机上的ARM浮点性能与x86进行比较。为此,我编写了以下代码:
#include "Linderdaum.h"
sEnvironment* Env = NULL;
volatile float af = 1.0f;
volatile float bf = 1.0f;
volatile int a = 1;
volatile int b = 1;
APPLICATION_ENTRY_POINT
{
Env = new sEnvironment();
Env->DeployDefaultEnvironment( "", "CommonMedia" );
double Start = Env->GetSeconds();
float Sum1 = 0.0f;
for ( int i = 0; i != 200000000; i++ ) { Sum1 += af + bf; }
double End = Env->GetSeconds();
Env->Logger->Log( L_DEBUG, LStr::ToStr( Sum1, 4 ) );
Env->Logger->Log( L_DEBUG, "Float: " + LStr::ToStr( End-Start, 5 ) );
Start = Env->GetSeconds();
int Sum2 = 0;
for ( int i = 0; i != 200000000; i++ ) { Sum2 += a + b; }
End = Env->GetSeconds();
Env->Logger->Log( L_DEBUG, LStr::ToStr( Sum2, 4 ) );
Env->Logger->Log( L_DEBUG, "Int: " + LStr::ToStr( End-Start, 5 ) );
Env->RequestExit();
APPLICATION_EXIT_POINT( Env );
}
APPLICATION_SHUTDOWN
{}
以下是不同目标和编制者的结果。
1。 Core i7 920上的Windows PC。
VS 2008,调试版本,Win32 / x86
(Main):01:30:11.769 Float: 0.72119
(Main):01:30:12.347 Int: 0.57875
float
比int
慢。
VS 2008,调试版本,Win64 / x86-64
(Main):01:43:39.468 Float: 0.72247
(Main):01:43:40.040 Int: 0.57212
VS 2008,发布版本,Win64 / x86-64
(Main):01:39:25.844 Float: 0.21671
(Main):01:39:26.060 Int: 0.21511
VS 2008,发布版本,Win32 / x86
(Main):01:33:27.603 Float: 0.70670
(Main):01:33:27.814 Int: 0.21130
int
正在取得领先地位。
2。三星Galaxy S智能手机。
GCC 4.3.4,armeabi-v7a,-mfpu = vfp -mfloat-abi = softfp -O3
01-27 01:31:01.171 I/LEngine (15364): (Main):01:31:01.177 Float: 6.47994
01-27 01:31:02.257 I/LEngine (15364): (Main):01:31:02.262 Int: 1.08442
float
严重慢于int
。
现在让我们改变循环中乘法的加法:
float Sum1 = 2.0f;
for ( int i = 0; i != 200000000; i++ )
{
Sum1 *= af * bf;
}
...
int Sum2 = 2;
for ( int i = 0; i != 200000000; i++ )
{
Sum2 *= a * b;
}
VS 2008,调试版本,Win32 / x86
(Main):02:00:39.977 Float: 0.87484
(Main):02:00:40.559 Int: 0.58221
VS 2008,调试版本,Win64 / x86-64
(Main):01:59:27.175 Float: 0.77970
(Main):01:59:27.739 Int: 0.56328
VS 2008,发布版本,Win32 / x86
(Main):02:05:10.413 Float: 0.86724
(Main):02:05:10.631 Int: 0.21741
VS 2008,发布版本,Win64 / x86-64
(Main):02:09:58.355 Float: 0.29311
(Main):02:09:58.571 Int: 0.21595
GCC 4.3.4,armeabi-v7a,-mfpu = vfp -mfloat-abi = softfp -O3
01-27 02:02:20.152 I/LEngine (15809): (Main):02:02:20.156 Float: 6.97402
01-27 02:02:22.765 I/LEngine (15809): (Main):02:02:22.769 Int: 2.61264
问题是:我缺少什么(任何编译器选项)? ARM设备上的浮点数学运算是否真的慢(与int相比)?
答案 0 :(得分:4)
-mfloat-abi=softfp
显式调用模拟浮点。检查Galaxy的规格,如果可能的话用硬件FP编译。
并非所有ARM CPU都支持硬件浮点开始。 NDK的ARMEABI默认设置调用模拟FP - 它应该与无FP机器兼容。充其量,您可以对CPU功能进行一些运行时分支。
答案 1 :(得分:4)
@Seva Alekseyev -mfloat-abi
标志仅控制浮点值如何传递给函数。使用普通寄存器传递softfp
值。使用FPU寄存器传递hardfp
值。 -mfloat-abi
标志不控制使用哪些硬件指令。
基本上softfp
用于保持与没有FPU的设备的向后兼容性。对于具有FPU的设备,使用softfp
将导致额外的开销。
@Sergey K比较x86和ARM就像比较苹果和橙子。它们是两个非常不同的平台。 ARM的主要设计目标是低功耗而不是速度。您可以使用hardfp
看到一些性能提升。还有一个4.6版本的编译器可用。考虑到架构差异,我认为你的结果是合理的。
答案 2 :(得分:4)
这些结果是可信的。
Exynos 3 SoC中使用的Cortex-A8内核具有非流水线VFP实现。我不记得我头顶的确切数字,但我的回忆是VFP加法和乘法的吞吐量是该核心每8个周期的操作顺序。
好消息:这是一个非常古老的SoC,而较新的ARM SoC具有更强大的VFP实现 - 添加,子和乘法完全流水线化,吞吐量大大提高。此外,一些(但不是全部)Cortex-A8 SoC支持NEON,它为您提供完全流水线的单精度浮点。
答案 3 :(得分:3)
请参阅http://github.com/dwelch67/stm32f4d,参见float03目录
测试比较了这两个函数固定vs浮点数
.thumb_func
.globl add
add:
mov r3,#0
loop:
add r3,r0,r1
sub r2,#1
bne loop
mov r0,r3
bx lr
.thumb_func
.globl m4add
m4add:
vmov s0,r0
vmov s1,r1
m4loop:
vadd.f32 s2,s0,s1
sub r2,#1
bne m4loop
vmov r0,s2
bx lr
结果并不太令人惊讶,0x4E2C时间是固定点而0x4E2E是浮点数,浮点测试函数中有一些额外的指令可能会导致差异:
00004E2C
00004E2C
00004E2E
00004E2E
00004E2C
00004E2E
stm32f4中的fpu仅限于其大兄弟姐妹中发现的vfp的单精度版本。您应该能够使用vfp硬件在任何armv7上执行上述测试。
通过链接__aeabi_fadd函数并且每次通过循环进行额外调用,加上内存访问的额外时间,可能在库外部或内部(vmov)转换库函数等,可以添加到您所看到的内容。答案当然是在反汇编中。