http://blog.chinaunix.net/uid-22545494-id-316735.html

作者: Sam(甄峰)  sam_code@hotmail.com

一:早期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        vldr    s14, [r1]
  44:   e51b200c        ldr     r2, [fp, #-12]
  48:   e59f3058        ldr     r3, [pc, #88]   ; a8 <test_f32bit_addition+0xa8>
  4c:   e0831102        add     r1, r3, r2, lsl #2
  50:   edd17a00        vldr    s15, [r1]
  54:   ee777a27        vadd.f32        s15, s14, s15
  58:   e59f304c        ldr     r3, [pc, #76]   ; ac <test_f32bit_addition+0xac>
  5c:   edc37a00        vstr    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 <test_f32bit_addition+0xb0>
  74:   e1520003        cmp     r2, r3
  78:   daffffed        ble     34 <test_f32bit_addition+0x34>
  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 <test_f32bit_addition+0xb0>
  90:   e1520003        cmp     r2, r3
  94:   daffffe3        ble     28 <test_f32bit_addition+0x28>
  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 <test_f32bit_addition>:
   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 <test_f32bit_addition+0x90>
  28:   e3a03000        mov     r3, #0
  2c:   e50b300c        str     r3, [fp, #-12]
  30:   ea00000f        b       74 <test_f32bit_addition+0x74>
  34:   e51b200c        ldr     r2, [fp, #-12]
  38:   e59f3068        ldr     r3, [pc, #104]  ; a8 <test_f32bit_addition+0xa8>
  3c:   e7932102        ldr     r2, [r3, r2, lsl #2]
  40:   e51b100c        ldr     r1, [fp, #-12]
  44:   e59f3060        ldr     r3, [pc, #96]   ; ac <test_f32bit_addition+0xac>
  48:   e7933101        ldr     r3, [r3, r1, lsl #2]
  4c:   e1a00002        mov     r0, r2
  50:   e1a01003        mov     r1, r3
  54:   ebfffffe        bl      0 <__aeabi_fadd>
  58:   e1a03000        mov     r3, r0
  5c:   e1a02003        mov     r2, r3
  60:   e59f3048        ldr     r3, [pc, #72]   ; b0 <test_f32bit_addition+0xb0>
  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 <test_f32bit_addition+0xb4>
  7c:   e1520003        cmp     r2, r3
  80:   daffffeb        ble     34 <test_f32bit_addition+0x34>
  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 <test_f32bit_addition+0xb4>
  98:   e1520003        cmp     r2, r3
  9c:   daffffe1        ble     28 <test_f32bit_addition+0x28>
  a0:   e24bd004        sub     sp, fp, #4
  a4:   e8bd8800        pop     {fp, pc}

则不包含VFP指令。

且去调用 __aeabi_fadd

ARM的GCC 编译选项:

http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/ARM-Options.html#ARM-Options

附录1 :VFP 指令

附录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.

Sam不明白为什么 hard不能使用。只好使用softfp

kernel 对浮点的支持的更多相关文章

  1. R kernel for Jupyter Notebook 支持r

    1/2) Installing via supplied binary packages(default on Windows + Mac OS X) You can install all pack ...

  2. Linux kernel 4.9及以上开启TCP BBR拥塞算法

    Linux kernel 4.9及以上开启TCP BBR拥塞算法 BBR 目的是要尽量跑满带宽, 并且尽量不要有排队的情况, 效果并不比速锐差 Linux kernel 4.9+ 已支持 tcp_bb ...

  3. hisicv200 exfat支持

    由于项目中需要128Gsd卡支持.所以内核里面需要支持exfat 1.exfat 由于版权问题,所以linux kernel一直都没法支持,由于某些公司在linux kernel 3.9版本开源exf ...

  4. 用Qemu模拟vexpress-a9 (五) --- u-boot引导kernel,device tree的使用

    环境介绍 Win7 64 + Vmware 11 + ubuntu14.04 32 u-boot 版本:u-boot-2015-04 Linux kernel版本:linux-3.16.y busyb ...

  5. 浮点优化选项 -ffast-math:极大地提高浮点运算速度【转】

    转自:http://blog.csdn.net/zjujoe/article/details/2604157 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 关于浮点优化选项摘 ...

  6. linux 基本命令 [转]

    linux 基本命令 1.ls  (list 显示当前目录下文件和目录 ls -l 详细显示 =ll ) [root@linux ~]# ls [-aAdfFhilRS] 目录名称 [root@lin ...

  7. linux常用命令大全(转)

    由于记忆力有限,把平时常用的Linux命令整理出来,以便随时查阅: linux 基本命令 ls     (list 显示当前目录下文件和目录 ls -l 详细显示 =ll ) [root@linux ...

  8. linux常用命令 http://mirrors.163.com/ubuntu-releases/12.04/

    由于记忆力有限,把平时常用的Linux命令整理出来,以便随时查阅: linux 基本命令 ls     (list 显示当前目录下文件和目录 ls -l 详细显示 =ll ) [root@linux ...

  9. Linux常用指令大全

    2017-03-25   16:35:42 刚开始学习Linux,由于记忆力有限,把平时常用的Linux命令整理出来,以便随时查阅:  linux 基本命令    ls     (list 显示当前目 ...

随机推荐

  1. [MAC]2015款MACBOOK使用BOOTCAMP安装WIN8.1+多分区

    注意事项: 2013年以前,带光驱的,请使用WinClone安装WIN7或WIN8,或可使用BOOTCAMP制作WINDOWS安装光盘 13-14年,不带光驱的,也能使用WinClone安装WIN7和 ...

  2. mysql命令行导入sql脚本中文变问号问题

    之前一直用工具连接mysql虽然小问题不断也都无伤大雅,最近做金融云项目,只能通过服务器的内网访问数据库,也就是说只能在linux下通过命令行访问,在导入中文的时候发现都变成问号了,经过查询资料解决, ...

  3. MAC安装M2Crypto报command 'cc' failed with exit status 1

    出错分析主要是因为由于OSX升级之后 /usr/include 没有了,使用命令修改swig寻址路径: sudo env LDFLAGS="-L$(brew --prefix openssl ...

  4. 01HTTP服务&AJAX编程

    HTTP服务&AJAX编程 一.服务器         1. 什么是服务器? 能够提供某种服务的机器(计算机)称为服务器. 2.服务器的分类:              1.按系统分类:Lin ...

  5. C# 一些知识点总结(一)_继承,多态,集合,关键字...

    内存中的三大存储区域:栈.堆.静态存储区域 new 关键字:new帮助我们做了三件事:1)在内存中开辟一块空间(开辟内存空间)2) 在开辟的空间中创建对象3)调用对象的构造函数进行初始化对象所以构造函 ...

  6. Ubuntu 命令大全

    一.文件目录类 1.建立目录:mkdir 目录名 2.删除空目录:rmdir 目录名 3.无条件删除子目录: rm -rf 目录名 4.改变当前目录:cd 目录名 (进入用户home目录:cd ~:进 ...

  7. GridView控件RowDataBound事件中获取列字段途径

    今天不知道怎么回事怎么也找不到gridview列中的控件,关键是其为编辑时隐藏域中的控件,取值就很成问题了,网上搜了很到,找到这个比较经典的东东了,可能大家都知道,但很少对比整理到一起,有多种方法可以 ...

  8. [译]Node.js - Event Loop

    介绍 在读这篇博客之前,我强列建议先阅读我的前两篇文章: Getting Started With Node.js Node.js - Modules 在这篇文章中,我们将学习 Node.js 中的事 ...

  9. ios AFNetworking 3.0 报错 : *** Assertion failure in -[AFHTTPRequestSerializer requestWithMethod:URLString:parameters:error:],

    AFNetWorking[:] *** Assertion failure -- :::] *** Terminating app due to uncaught exception 'NSInter ...

  10. ARCGIS Server 发布服务时出现的问题解决

    target='CFH.ConfigurationFactoryHost'  machine='IBM3850X5'  thread='24072'  elapsed='0.31200'>Ser ...