我提出了一些基于机器学习的算法,该算法基于树莓pi 3,具有大量存储系数数组,不需要完全精度。
我尝试使用半精度浮点来存储这些数据,以减少程序内存(可能还有内存带宽)占用。
算法的其余部分保持不变。
在使用__fp16
时,我比较了flat32和flat16版本的性能损失(显著的:我测试程序的33%运行时),尽管cpu应该支持转换。
我查看了asembler输出,还创建了一个sinple函数,该函数只读取一个值,并将其作为浮点返回,并且似乎使用了一些库函数调用来进行转换。(与实际代码中调用的函数相同)
rapspberry的cpu应该有半精度硬件支持,所以我希望看到一些指令加载数据,而不会看到任何性能影响(或者看到由于内存带宽需求减少而带来的改进)
我正在使用以下编译器标志:
-O3 -mfp16-format=alternative -mfpu=neon-fp16 -mtune=cortex-a53 -mfpu=neon
这里是小测试函数的小代码和汇编器输出:
const float test(const Coeff *i_data, int i ){
return (float)(i_data[i]);
}
对系数使用浮点数:
.align 2
.global test
.syntax unified
.arm
.fpu neon
.type test, %function
test:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
add r1, r0, r1, lsl #2 @ tmp118, i_data, i,
vldr.32 s0, [r1] @, *_5
bx lr @
将fp16用于系数(-mfp16格式=可选):
.align 2
.global test
.syntax unified
.arm
.fpu neon
.type test, %function
test:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
lsl r1, r1, #1 @ tmp118, i,
push {r4, lr} @
ldrh r0, [r0, r1] @ __fp16 @, *_5
bl __gnu_h2f_alternative @
vmov s0, r0 @,
pop {r4, pc} @
对于系数(mfp16格式=ieee),使用fp16:
.align 2
.global test
.syntax unified
.arm
.fpu neon
.type test, %function
test:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
lsl r1, r1, #1 @ tmp118, i,
push {r4, lr} @
ldrh r0, [r0, r1] @ __fp16 @, *_5
bl __gnu_h2f_ieee @
vmov s0, r0 @,
pop {r4, pc} @
我错过了什么吗?
在ARM的网站上:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0774d/chr1421838476257.html
注意__fp16类型仅是一种存储格式。出于算术和其他操作的目的,C或C表达式中的__fp16值会自动提升为浮点数。
由于只能指定一次,编译器标志将覆盖早期的mfpu=neon-fp16。
这是一个错误,它被设置了两次(它被添加到Makefile的不同位置)。
但由于raspberry 3有一个始终支持fp16的vfpv4,因此最好的规范是mfpu=neon-vfpv4。
在这种情况下,编译器不会为转换生成库调用。
编辑:根据这个ghist-mfpu=neon-fp-armv8-mneon-for-64位可以用于Raspberry 3。
问题内容: 是否在任何地方都有Java库可以对IEEE 754半精度 数字执行计算或将其与双精度数字进行转换? 这些方法中的任何一种都是合适的: 将数字保持为半精度格式,并使用整数算术和位扭曲(如MicroFloat的单精度和双精度)进行计算 以单精度或双精度执行所有计算,转换成半精度以进行传输(在这种情况下,我需要经过良好测试的转换函数。) 编辑 :转换需要100%准确- 输入文件中 有 很多N
问题内容: 我正在尝试使用包含大量16位浮点数的javascript读取二进制文件。可以肯定的是它是IEEE标准,低位字节序。将两个字节读入一个int非常简单,但是从那里将其扩展为一个完整的浮点数并没有太大的成功。有什么线索吗? 问题答案: 我最终根据Wikipedia页面上的信息实现了自己的解析器。它可能不是最快的,但是我对此不太担心。这里是那些好奇的人:
我想做的:用Raspi零 我用的是: 覆盆子皮零 我遵循以下流程: 使用rasp-pi 3作为接入点 使用rasp-pi 2和2 wifi加密狗作为路由器(http://qiita.com/mt08/items/4247894833bd4dcb27e2#_reference-27aa37c4be7f602667ff) 在2台仪器中,带有2个加密狗的raspi可以连接到wifi路由器,同时成为一个接
谢谢
问题内容: $a = ‘35’; $b = ‘-34.99’; echo ($a + $b); 结果为0.009999999999998 这是怎么回事?我想知道为什么我的程序不断报告奇怪的结果。 为什么PHP不返回预期的0.01? 问题答案: 因为浮点运算!=实数运算。对于一些浮子和,由不精确性引起的差异的说明是。这适用于使用浮点数的任何语言。 由于浮点数是具有有限精度的二进制数,因此存在有限数量
本文向大家介绍Fortran 浮点数精度,包括了Fortran 浮点数精度的使用技巧和注意事项,需要的朋友参考一下 示例 类型的浮点数real不能有任何实数值。它们可以表示实数,最多可以包含一定数量的十进制数字。 FORTRAN 77保证了两种浮点类型,而最新的标准则至少保证了两种实数类型。实变量可以声明为 x这是默认类型的实数,并且y是比更大的十进制精度的实数x。在Fortran 2008中,十