fp32和fp16之间转换

       深度学习中我们一般使用浮点进行原始模型的训练推理,但是有时候我们希望占用更少的内存,加快推理速度,精度又要求没有特别高的情况下,假设硬件支持了fp16的加速优化,我们就可以使用。

        那么是如何处理float和fp16转换的,在介绍这个之前,有一个前置知识点就是fp32、fp16在内存中是怎么存储的,可以看这个这篇文章

下面贴下转换代码

fp32 ->fp16

typedef unsigned short half;

half nvFloat2Half(float m2)
{
/*
1、强制把float转为unsigned long(32bit),用来取对应bit的数
2、截取后23位尾数,右移13位,剩余10位,得到了fp16的尾数位(取高10位)
3、符号位直接右移16位,得到了fp16的符号位
4、截取指数的8位先右移13位,这里得到8位,但是我们只用到5位,左边多出的3位不用管
   由于之前0~255表示-127~128,调整过后变成 0~31表示-15~16,所以fp16情况下指数位是+15,
   所以这里需要在移位后指数的基础上减去(127-15) = 112(左移10位,因为指数是在bit10开始),
*/

    unsigned short t = ((m2 & 0x007fffff) >> 13) | ((m2 & 0x80000000) >> 16) 
        | (((m2 & 0x7f800000) >> 13) - (112 << 10));           
    if(m2 & 0x1000) 
        t++;                   // 四舍五入(尾数被截掉部分的最高位为1, 则尾数剩余部分+1)
    half h = *(half*)(&t);     // 强制转为half
    return h ;
}

fp16->fp32

float nvHalf2Float(half n)
{
    unsigned short frac = (n & 0x3ff) | 0x400;
    int exp = ((n & 0x7c00) >> 10) - 25;
    float m;
    if(frac == 0 && exp == 0x1f)
        m = INFINITY;
    else if (frac || exp)
        m = frac * pow(2, exp);
    else
        m = 0;
    return (n & 0x8000) ? -m : m;
}

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值