当前位置: 首页 > 知识库问答 >
问题:

gcc在覆盆子半精度浮点(binary16,替代,__fp16)使用库函数

田昊天
2023-03-14

我提出了一些基于机器学习的算法,该算法基于树莓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}    @

我错过了什么吗?


共有2个答案

巢靖
2023-03-14

在ARM的网站上:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0774d/chr1421838476257.html

注意__fp16类型仅是一种存储格式。出于算术和其他操作的目的,C或C表达式中的__fp16值会自动提升为浮点数。

盛超
2023-03-14

由于只能指定一次,编译器标志将覆盖早期的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中,十