硬件中的定点数与浮点数运算与相互转换

这些天在帮忙弄CNN卷积神经网络中的量化以及定点化,个人感觉定点化属于一种特殊的量化,由对应的进制表征,适合特定的运算器执行存储与运算。这里主要讲量化为定点数这一概念。

关于定点数,浮点数,小数,整数,原反补码,整形(int),浮点型(float,double),这些概念其实作为eecs的学生,我们应该都或多或少接触过,但是可能很少有人想为什么会有这些表示法,以及他们之间怎么转换,是什么关系,我们更多只是知道如何使用它们。但其实如果真的想理解计算机组成原理,计算机体系结构,或者想结合硬件设计与软件系统进行底层设计,达到更进一步的境界,我觉得还很有必要进一步学习。

闲话先不说了,步入正题吧。
首先是定点数。定点数这一概念,我觉得是最初的运算器使用的表征方法,整形数(int)其实是一种特殊的定点数,但其实定点数既可以表示小数(不仅仅是纯小数)也可以表示整数,补码的概念仅仅在整形数或者定点数上才勉强成立(另外说一句,补码是写给计算机看的,原码才是写给人看的,作为理解方便,在很多讲述的例子里面,我们直接使用原码进行分析即可)。而浮点数是另外一套计算系统,有对应配套的规则。

关于定点数,下面的第二篇博客写的很好:
https://blog.csdn.net/u010296036/article/details/68942134
https://blog.csdn.net/williamgavin/article/details/78743182
https://blog.csdn.net/baidu_31137467/article/details/83003585
https://blog.csdn.net/yanxiaopan/article/details/76853040
https://blog.csdn.net/meng4411yu/article/details/8668646
https://blog.csdn.net/niaolianjiulin/article/details/82764511#5__144
https://blog.csdn.net/qq_41359358/article/details/84202934
https://blog.csdn.net/qq_38791897/article/details/88888267
https://blog.csdn.net/qq_38791897/article/details/88766388
https://blog.csdn.net/qq_38791897/article/details/88778282

其实关于定点数编程是一门很大的学问,你可以在标准定点数的基础上修改,以适应你的硬件需求。
这里有一个参考:
https://blog.csdn.net/u013580397/article/details/80878213

但是里面有个例子没解释好,2.2小节,例3是针对例1而言的。还有一个例子有误,作者也没有进行更改,4.4小节,你看看就知道他的表格有问题了。具体可以查看评论,有人指正了。

关于浮点数,我之前写过一篇博客,参见:
https://blog.csdn.net/edward_zcl/article/details/89439128

里面想介绍了单精度与双精度浮点的存储格式,可以说非常详细了。
但是其实关于定点数,浮点数,还有很多需要注意的点,比如溢出,比如无效值,舍入处理等等,讲的还不算详细。个人觉得真正讲的比较详细的是这篇:https://www.cnblogs.com/kevinq/p/4480563.html
你需要注意他说的浮点数各个域的表示范围与表示精度,以及特殊值处理。

这里我再补充一点,定点数里面叫定标,Q值(S值),整数位,小数位,符号位,而浮点数里面叫指数部分(阶码),尾数部分,符号位。像DSP这种可能既可以支持定点运算,也可以支持浮点运算,而FPGA可能就不太能行了,只能支持定点运算,没有这样的底层元件库,使用verilog也不支持实现浮点运算器的综合,甚至像一般的DSP定点运算器也需要注意各种溢出的情况。并且,定点运算非常呆板,表示范围IE以及数据精度都不够大,而浮点运算则不一样,因此在高级计算机中,一般都使用了浮点运算器,但代价就是设计更加复杂,功耗也更高。
FPGA中定点数与浮点数之间转换是有精度损失的,其实这就我们往往都默认了浮点数表示范围很大,并且精度也很大,其实事实上也确实这样,但是并不是无限大,通过上面链接你应该也知道,就算是浮点数,也无法精确表示很多十进制小数。但在这里说明转化的时候,往往忽略了这个区别。
关于FPGA定点数的处理,以及定点数与浮点数之间的转换可以参见:
https://blog.csdn.net/zhoufan900428/article/details/9037467
https://blog.csdn.net/iamshaofa/article/details/49805045
https://blog.csdn.net/vict_wang/article/details/81179146
https://blog.csdn.net/alinyua/article/details/79716094
https://blog.csdn.net/Victor145/article/details/82320588
https://blog.csdn.net/github_33678609/article/details/53465626
http://www.elecfans.com/d/612184.html
https://blog.csdn.net/chenqiang1026/article/details/43705367

很多转换都是用C来进行浮点数据模拟定点运算的,现在一些python包比如:TFlite也有种工具内嵌其中,前几天还看到了一个matlab的工具,但是可能不够灵活,用的人不够多。。参见:
https://blog.csdn.net/u012573961/article/details/80377757
https://blog.csdn.net/truecrab/article/details/79486431
https://blog.csdn.net/sunlight369/article/details/42742235

其实设计具有很强动态范围,同时具有很高精度的定点运算器,也是一门学问,如何处理溢出保护机制(双符号位,单符号位等)。
其次关于定点数,还想说的是,其实既然是定点数,那么在处理正负数的时候,就是使用补码进行运算的,其实这也是及其往往为什么更适合使用补码进行存储与运算的,因为机器往往都智是做加法,关于定点数补码运算其实也有一套理论,还有相应的证明,现代计算机中有符号定点运算,都是使用的这一套理论。简单一点,关于补码运算这可以使用钟表来解释。
可以参见:
https://blog.csdn.net/kebu12345678/article/details/81563987
https://blog.csdn.net/qhw5279/article/details/79630912
关于DSP中如何灵活处理定点数的,可以参考:
https://blog.csdn.net/ky2qt/article/details/7054604
https://blog.csdn.net/sonictl/article/details/9018681
https://blog.csdn.net/kebu12345678/article/details/81673161
https://blog.csdn.net/wyq_841943/article/details/70808477
https://blog.csdn.net/xinanzhung/article/details/16844797
还有就是定点数与浮点数的转换,在上面连接中其实应该已经得很清楚了,通过乘或除你的Q值即可。在这里再附上两个:
https://blog.csdn.net/kyopeng123/article/details/51144034
https://www.jianshu.com/p/c3591e1efc9b
https://blog.csdn.net/baidu_24281959/article/details/52015811

里面有两句话,
1、“如果加法/减法的结果超出16位的表示范围,则必须保留32位结果,以保证运算的精度,否则可能会出现严重的精度丢失。”
这句话我认同,毕竟溢出了肯定接下来出现的差错就会很大了。但是其实对于定点加法,难道不是溢出的话增加一位,也就是17位就可以解决吗,为什么一定要32位这么大,可能他认为计算都是16,32这样的位宽吧,毕竟没有17的数据类型啊。。可能是这样。
2、“浮点数转换为定点数时,为了降低截尾误差,可以在取整前可以先加上0.5,视情况而定。”
这句话我认为他掐头去尾了,因为突然冒出了个+0.5,这个应该是有原文的,毕竟说了截尾误差,应该是默认了在定点数里面,机器一般使用舍弃,也就是截断,既不是四舍五入,也不是之前介绍那么些个偶数舍入等等,所以会造成误解。原文在这里:
http://www.elecfans.com/d/612184.html
https://www.cnblogs.com/s_agapo/archive/2012/03/20/2407332.html
里面前面其实还有句话,向下取整。。这些个人博客中不写明白,真的是把人弄的莫名其妙。

好了,基本上所有的关于定点数与浮点数的内容都说的差不多了,作为纯编程人员,确实没有必要把这些弄清楚,但如果想深入理解计算机体系结构,以及从底层设计硬件以及对应的架构设计,这些内容是必备的。


以上只是理论介绍,下面介绍一下相关的几篇量化论文。

最近发现一个比较朴素的博客:
https://blog.csdn.net/ffmpeg4976/article/details/54375225
https://blog.csdn.net/u013498583/article/details/80360601

卷积网络中定点化专利:
http://www.jigao616.com/zhuanlijieshao_13359202.aspx
http://www.jigao616.com/zhuanlijieshao_19009606.aspx
http://www.xjishu.com/zhuanli/55/201810206021.html
http://www.jigao616.com/zhuanlijieshao_13359202.aspx
http://www.xjishu.com/zhuanli/55/201611033156.html

你可能感兴趣的:(计算机基础知识)