ARM浮点运算

原帖地址:http://blog.sina.com.cn/s/blog_602f87700100r5xe.html

一:早期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)来执行。

 

 

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

这里Sam是这样理解的:

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

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

2. 编译器支持将浮点运算翻译成硬件浮点运算指令。

 

1. Kernle的支持:

如果Kernel不支持浮点协处理器,则因为协处理器寄存器等使用权限等问题,协处理器对应指令无法运行。

网络上有位高手指出:

CP15 c1 协处理器访问控制寄存器,这个寄存器规定了用户模式和特权对协处理器的访问权限。我们要使用VFP当然要运行用户模式访问CP10和CP11。
另外一个寄存器是VFP的FPEXC Bit30这是VFP功能的使用位。
其实操作系统在做了这两件事情之后,用户程序就可以使用VFP了。当然,Kernel 除了这2件事外,还处理了其他一些事情。

 

Sam看了看Kernel中对应代码,发现是汇编后就放弃继续研究了。

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(Floating Point Accelerator)指令。 FPA指令再去查看是否有浮点模拟器。

还可以将浮点运算指定为VFP(vector floating point)指令。

 

 

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

Sam有个测试程序,测试CPU浮点性能。例如:浮点加减乘除等运算的时间长度:

 

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 <test_F32bit_addition>:
   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 <test_F32bit_addition+0x88>
  28:   e3a03000        mov     r3, #0
  2c:   e50b300c        str     r3, [fp, #-12]
  30:   ea00000d        b       6c <test_F32bit_addition+0x6c>
  34:   e51b200c        ldr     r2, [fp, #-12]
  38:   e59f3064        ldr     r3, [pc, #100]  ; a4 <test_F32bit_addition+0xa4>
  3c:   e0831102        add     r1, r3, r2, lsl #2
  40:   ed917a00        

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章