kernel 对浮点的支持
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 指令
-
浮点绝对值、求反和平方根。
-
浮点加法、减法和除法。
VMUL、VMLA、VMLS、VNMUL、VNMLA 和 VNMLS
浮点乘法和乘加,包含可选求反。
-
浮点数比较。
-
在单精度数和双精度数之间转换。
-
在浮点数和整数之间转换。
-
在浮点数和定点数之间转换。
-
在半精度和单精度浮点数之间转换。
-
将浮点常数插入单精度或双精度寄存器。
附录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 对浮点的支持的更多相关文章
- R kernel for Jupyter Notebook 支持r
1/2) Installing via supplied binary packages(default on Windows + Mac OS X) You can install all pack ...
- Linux kernel 4.9及以上开启TCP BBR拥塞算法
Linux kernel 4.9及以上开启TCP BBR拥塞算法 BBR 目的是要尽量跑满带宽, 并且尽量不要有排队的情况, 效果并不比速锐差 Linux kernel 4.9+ 已支持 tcp_bb ...
- hisicv200 exfat支持
由于项目中需要128Gsd卡支持.所以内核里面需要支持exfat 1.exfat 由于版权问题,所以linux kernel一直都没法支持,由于某些公司在linux kernel 3.9版本开源exf ...
- 用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 ...
- 浮点优化选项 -ffast-math:极大地提高浮点运算速度【转】
转自:http://blog.csdn.net/zjujoe/article/details/2604157 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 关于浮点优化选项摘 ...
- linux 基本命令 [转]
linux 基本命令 1.ls (list 显示当前目录下文件和目录 ls -l 详细显示 =ll ) [root@linux ~]# ls [-aAdfFhilRS] 目录名称 [root@lin ...
- linux常用命令大全(转)
由于记忆力有限,把平时常用的Linux命令整理出来,以便随时查阅: linux 基本命令 ls (list 显示当前目录下文件和目录 ls -l 详细显示 =ll ) [root@linux ...
- linux常用命令 http://mirrors.163.com/ubuntu-releases/12.04/
由于记忆力有限,把平时常用的Linux命令整理出来,以便随时查阅: linux 基本命令 ls (list 显示当前目录下文件和目录 ls -l 详细显示 =ll ) [root@linux ...
- Linux常用指令大全
2017-03-25 16:35:42 刚开始学习Linux,由于记忆力有限,把平时常用的Linux命令整理出来,以便随时查阅: linux 基本命令 ls (list 显示当前目 ...
随机推荐
- JS splice() 定义和用法
定义和用法 splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目. 注释:该方法会改变原始数组. 语法 arrayObject.splice(index,howmany,item1, ...
- Delphi里如何让程序锁定在桌面上,win+d都无法最小化
procedure TForm29.FormCreate(Sender: TObject); begin Windows.SetParent(Self.Handle, FindWindowEx(Fin ...
- 非正常关闭myeclicps后,出现错误Errors occurred during the build.的解决方法
我的myeclicps是10.7版本由于非正常关闭,在启动tomcat时候出现了问题. 解决法案: 1.关闭myeclicps. 2.打开你的myeclicps的工作空间(workspace自己设置的 ...
- ORACLE分区--表分区
.love_flying_snow Oracle表分区 Oracle . 废话少说,直接讲分区语法. Oracle表分区分为四种:范围分区,散列分区,列表分区和复合分区. 一:范围分区 就是根据数据库 ...
- 配置 samba 实现文件共享
用于实现文件共享 netstat -apn|grep smb 可以按到 smb服务,需要开启139 .445端口号 需要在防火墙添加如下规则vi /etc/sysconfig/iptables -A ...
- C# 委托和事件 与 观察者模式(发布-订阅模式)讲解 by天命
使用面向对象的思想 用c#控制台代码模拟猫抓老鼠 我们先来分析一下猫抓老鼠的过程 1.猫叫了 2.所有老鼠听到叫声,知道是哪只猫来了 3.老鼠们逃跑,边逃边喊:"xx猫来了,快跑啊!我是老鼠 ...
- 微信App支付通知验签
微信异步通知: [AcceptVerbs("POST")] public void Notify() { //编码(101-登录无效,102-账号无效,200-成功,201-失败, ...
- 【Debian】非法关机后无法联网 connect: network is unreachable
某一天,突然发现无法ssh登录虚拟机内的debian系统,一直认为是ssh的问题,然后无意间ping了ping百度,发现原来是debian系统没有联网....囧 首先,是虚拟机的网络设置检查. 打开V ...
- sql数据查询,在程序中较慢,在MS SQL2005 Management Studio中速度快,情况分析及解决
这两天遇到一个问题,在.net开发的网站,执行sql查询,从sql profiler中监控卡看,执行时间22s. 但是拷出的sql在Management Studio中直接执行,时间仅4ms. 解决方 ...
- JavaScript基础知识整理(1)
粗略理解,努力入门中 1.在html中引入外部脚本: <script src="filename.js"></script> 2.注释: 多于一行的长注 ...