您的位置 首页 开关

ARM 浮点运算详解

一:早期ARM上的浮点模拟器:早期的ARM没有协处理器,所以浮点运算是由CPU来模拟的,即所需浮点运算均在浮点运算模拟器(floatmathemul…

一:前期ARM上的浮点模仿器:

前期的ARM没有协处理器,所以浮点运算是由CPU来模仿的,即所需浮点运算均在浮点运算模仿器(float math emulation)上进行,需求的浮点运算,常要消耗数千个循环才干碑文结束,因而特别缓慢。

直到今日,在ARM Kernel装备时,都有如下选项:

Floating point emulation —>

[ ] NWFPE math emulation

[ ] FastFPE math emulation (EXPERIMENTAL)

在这儿,能够装备ARM 浮点模仿器。

浮点模仿器 模仿浮点是利用了undefined instrction handler,在运算过程中遇到浮点核算是发生异常中止,这么做带来的结果是带来极频频的exception,大大增加中止推迟,下降体系实时性。

二:软浮点技能:

软浮点支撑是由穿插东西链供给的功用,与Linux内核无关。当运用软浮点东西链编译浮点操作时,编译器会用内联的浮点库替换掉浮点操作,使得生成的机器码彻底不含浮点指令,可是又能够完结正确的浮点操作。

三:浮点协处理器:

在较新版本的ARM中,能够增加协处理器。 一些ARM CPU为了更好的处理浮点核算的需求,增加了浮点协处理器。

并界说了浮点指令集。 假如不存在实践的硬件,则这些指令被截获并由浮点模仿器模块(FPEmulator)来碑文。

四: 硬件浮点协处理器以及对应指令集的运用:

想要运用硬件浮点协处理器来协助运算Application中的浮点运算。需求以下几个前提条件:

1. Kernel中设置支撑硬件协处理器。

2. 编译器支撑将浮点运算翻译成硬件浮点运算指令,或许在需求浮点运算的时分手动调用相应的浮点运算指令。

1. Kernle的支撑:

假如Kernel不支撑浮点协处理器,则由于协处理器寄存器等运用权限等问题,协处理器对应指令无法运转。

网络上有位高手指出:

CP15 c1 协处理器拜访操控寄存器,这个寄存器规则了用户形式和特权对协处理器的拜访权限。咱们要运用VFP当然要运转用户形式拜访CP10和CP11。
别的一个寄存器是VFP的FPEXC Bit30这是VFP功用的运用位。
其实操作体系在做了这两件工作之后,用户程序就能够运用VFP了。当然,Kernel 除了这2件事外,还处理了其他一些工作。

Floating point emulation —>
[*]VFP-format floating point maths

Include VFP support code in the kernel. This is needed IF your hardware includes a VFP unit.

2. 编译器指定浮点指令:

编译器能够显式指定将浮点运算翻译成何种浮点指令。

假如编译器支撑软浮点,则其或许会将浮点运算翻译成编译器中自带的浮点库。则不会有真实的浮点运算。

不然,能够翻译成FPA(FloatingPointAccelerator)指令。 FPA指令再去检查是否有浮点模仿器。

还能够将浮点运算指定为VFP(vectorfloating point)指令或许neon向量浮点指令。

五. 编译器指定编译硬浮点指令:

测验浮点加减乘除等运算的时刻长度:

float src_mem_32[1024] = {1.024};

float dst_mem_32[1024] = {0.933};

for(j = 0; j < 1024; j++)
{
for(i = 0; i < 1024; i++)
{
src_32 = src_mem_32[i] + dst_mem_32[i];
}
}

经过printf 核算前后毫秒数的差值来看核算才能。

编译:

arm-hisiv200-linux-gcc -c -Wall fcpu.c -o fcpu.o

arm-hisiv200-linux-gcc fcpu.o -o FCPU -L./

运转,则得到32位浮点数加1024次所需求时刻。

假如要运用VFP呢?

arm-hisiv200-linux-gcc -c -Wall -mfpu=vfp -mfloat-abi=softfp fcpu.c -o fcpu.o

arm-hisiv200-linux-gcc -Wall -mfpu=vfp -mfloat-abi=softfp fcpu.o -o FCPU -L./

则运转后发现,所需求时刻简直减小了一半。 阐明仍是十分有作用的。

关于-mfpu -mfloat-abi解说:见附录2。

别的,怎么才干在直观的检查出是否运用VFP呢?

能够经过观察编译出的ASM程序得到序幕。

#arm-hisiv200-linux-objdump -d fcpu.o

00000000 :
0: e52db004 push {fp} ; (str fp, [sp, #-4]!)
4: e28db000 add fp, sp, #0
8: e24dd00c sub sp, sp, #12
c: e3a03000 mov r3, #0
10: e50b300c str r3, [fp, #-12]
14: e3a03000 mov r3, #0
18: e50b3008 str r3, [fp, #-8]
1c: e3a03000 mov r3, #0
20: e50b3008 str r3, [fp, #-8]
24: ea000017 b 88
28: e3a03000 mov r3, #0
2c: e50b300c str r3, [fp, #-12]
30: ea00000d b 6c
34: e51b200c ldr r2, [fp, #-12]
38: e59f3064 ldr r3, [pc, #100] ; a4
3c: e0831102 add r1, r3, r2, lsl #2
40: ed917a00vldr s14, [r1]
44: e51b200c ldr r2, [fp, #-12]
48: e59f3058 ldr r3, [pc, #88] ; a8
4c: e0831102 add r1, r3, r2, lsl #2
50: edd17a00vldr s15, [r1]
54: ee777a27vadd.f32 s15, s14, s15
58: e59f304c ldr r3, [pc, #76] ; ac
5c: edc37a00vstr s15, [r3]
60: e51b300c ldr r3, [fp, #-12]
64: e2833001 add r3, r3, #1
68: e50b300c str r3, [fp, #-12]
6c: e51b200c ldr r2, [fp, #-12]
70: e59f3038 ldr r3, [pc, #56] ; b0
74: e1520003 cmp r2, r3
78: daffffed ble 34
7c: e51b3008 ldr r3, [fp, #-8]
80: e2833001 add r3, r3, #1
84: e50b3008 str r3, [fp, #-8]
88: e51b2008 ldr r2, [fp, #-8]
8c: e59f301c ldr r3, [pc, #28] ; b0
90: e1520003 cmp r2, r3
94: daffffe3 ble 28
98: e28bd000 add sp, fp, #0
9c: e49db004 pop {fp} ; (ldr fp, [sp], #4)
a0: e12fff1e bx lr

这儿显着包括vfp指令。 所以是运用vfp指令的:

arm-hisiv200-linux-gcc -c -Wall -mfpu=vfp -mfloat-abi=softfp fcpu.c -o fcpu.o

留意:VFP 指令指令在附录1中。

假如运用:

arm-hisiv200-linux-gcc -c -Wall fcpu.c -o fcpu.o

#arm-hisiv200-linux-objdump -d fcpu.o

00000000 :
0: e92d4800 push {fp, lr}
4: e28db004 add fp, sp, #4
8: e24dd008 sub sp, sp, #8
c: e3a03000 mov r3, #0
10: e50b300c str r3, [fp, #-12]
14: e3a03000 mov r3, #0
18: e50b3008 str r3, [fp, #-8]
1c: e3a03000 mov r3, #0
20: e50b3008 str r3, [fp, #-8]
24: ea000019 b 90
28: e3a03000 mov r3, #0
2c: e50b300c str r3, [fp, #-12]
30: ea00000f b 74
34: e51b200c ldr r2, [fp, #-12]
38: e59f3068 ldr r3, [pc, #104] ; a8
3c: e7932102 ldr r2, [r3, r2, lsl #2]
40: e51b100c ldr r1, [fp, #-12]
44: e59f3060 ldr r3, [pc, #96] ; ac
48: e7933101 ldr r3, [r3, r1, lsl #2]
4c: e1a00002 mov r0, r2
50: e1a01003 mov r1, r3
54: ebfffffebl 0 <__aeabi_fadd>
58: e1a03000 mov r3, r0
5c: e1a02003 mov r2, r3
60: e59f3048 ldr r3, [pc, #72] ; b0
64: e5832000 str r2, [r3]
68: e51b300c ldr r3, [fp, #-12]
6c: e2833001 add r3, r3, #1
70: e50b300c str r3, [fp, #-12]
74: e51b200c ldr r2, [fp, #-12]
78: e59f3034 ldr r3, [pc, #52] ; b4
7c: e1520003 cmp r2, r3
80: daffffeb ble 34
84: e51b3008 ldr r3, [fp, #-8]
88: e2833001 add r3, r3, #1
8c: e50b3008 str r3, [fp, #-8]
90: e51b2008 ldr r2, [fp, #-8]
94: e59f3018 ldr r3, [pc, #24] ; b4
98: e1520003 cmp r2, r3
9c: daffffe1 ble 28
a0: e24bd004 sub sp, fp, #4
a4: e8bd8800 pop {fp, pc}

则不包括VFP指令。

且去调用 __aeabi_fadd

附录1 :VFP 指令

能够检查arm的realView文档。

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204ic/Bcffbdga.html

附录2:

-mfpu=name
-mfpe=number
-mfp=number
This specifies what floating point hardware (or hardware emulation) is available on the target. Permissible names are: fpa, fpe2, fpe3, maverick, vfp. -mfp and -mfpe are synonyms for -mfpu=fpenumber, for compatibility with older versions of GCC.

-mfloat-abi=name
Specifies which ABI to use for floating point values. Permissible values are: soft, softfp and hard.

soft and hard are equivalent to -msoft-float and -mhard-float respectively. softfp allows the generation of floating point instructions, but still uses the soft-float calling conventions.

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/dianyuan/kaiguan/264016.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部