“半精密”16位浮点运算

只需要16位的浮点运算格式的存储变得越来越流行。也被称为半精密binary16记忆时,格式是有用是一种稀缺资源。

内容

背景

IEEE 754标准,在1985年发表的定义格式的浮点数占32或64位的存储。这些格式被称为binary32binary64,或者更频繁双精度。多年MATLAB仅使用双精度和仍然是我们的默认格式。单精度逐渐添加了在过去的几年中,现在也完全支持。金宝app

IEEE 754的修订,于2008年出版,定义了一个只占16位浮点格式。被称为binary16,它主要是为了减少存储和内存带宽要求。因为它只提供了“半两”精度,使用实际的计算是有问题的。一个有趣的讨论其效用作为图像处理与动态范围是由增加格式工业光魔。硬件支持半精密现在金宝app可以在许多处理器,包括的GPU苹果iPhone 7。这里是一个链接到一个广泛的文章精密的一半NVIDIA GeForce GPU

浮点解剖学

一个浮点数的格式的特点是两个参数,p分数和碎片的数量的比特数的指数。我将考虑四个精度等级,季度,一半,,。quarter-precision格式是我发明的这篇博客;它不是标准实际上不是很有用。

特征参数的四双

p =[52] 4 10 23日;
q = (3、5、8、11);

这些值的p,和一个标志,在这个词的比特总数,w是2的幂。

w = p + q + 1
w = 8 16个32 64

归一化数据

大多数的浮点数归一化,表示为

$ $ x = (1 + f)下午\ 2 ^ $ $

分数f是美元的开区间的一半

$ $ 0 \ leq f < 1 $ $

f需要美元的二进制表示p位。换句话说2 ^ p f美元是一个整数的范围

$ $ 0 \ leq 2 ^ p f < 2 ^ $ $

指数e美元是一个整数的范围

$ $ - b + 1 \ \ leq leq e b $ $

量b是最大的指数和美元偏见

$ $ b = 2 ^ {q1} - 1 $ $

b = 2 ^ (q1) 1
15 127 1023 b = 3

规范化的小数部分号码是1 + f美元,但只有f美元需要存储。被称为领先1美元隐位

低于正常的

有两个值的指数e偏见的美元指数,e + b美元,达到最小的和最大的值可能表示位。最小的是

$ $ $ $ e + b = 0

对应的浮点数没有隐藏的领先一点。这些都是低于正常的denormal数字。

$ $ x = \点f 2 ^ {b} $ $

无穷,不是一个数字

最大可能的偏差指数

$ $ e + b = 2 ^ q1 $ $。

量指数领域的代表无极,或不是一个数字

浮点数的百分比是例外,因为他们是弱智者,无穷大或NaN增加精度降低。异常指数只有2美元值2 ^ q美元。对于双精度这是美元2/2 ^{11}$,小于百分之一的十分之一,但对于半精密2/2 ^ 5美元,超过6%。并完全我所有的玩具季度四分之一精度浮点数是例外。

编码符号位s = 0为非负和s = 1为负。和编码指数抵消偏见,b。然后可以用一个浮点数w位与

x = [s p e + b 2 ^ * f]

精度和范围

ε

如果无法表达一个实数与二进制扩展要求p位,它必须通过一个浮点数,确实有这样的二进制表示。这是舍入误差。描述精度的重要数量机ε,或每股收益。在MATLAB中,每股收益(x)是距离x下一个更大的(绝对值)浮点数。没有理由,每股收益是简单的区别1和下一个更大的浮点数。

格式shortg每股收益= 2。^ (- p)
每股收益= 0.0625 0.00097656 1.1921 2.2204 e-07 e-16

这告诉我们,双精度有利于约16精度的小数位数,单7小数位数,约一半,几乎不超过一个季度。

最大浮点数

如果一个实数,或者一个算术运算的结果,太大代表,它溢出和被替换。最大的浮点数不溢出

最大浮点数= 2 ^ b * (2-eps)。
最大浮点数= 15.5 65504 3.4028 e+38 1.7977 e + 308

最小正浮点数

下溢更加复杂和代表性非常小的数字。最小的规格化的浮点数

最小正浮点数= 2。^ (- b + 1)
最小正浮点数= 0.25 6.1035 1.1755 e-05 38吗2.2251 e - 308

但也有数字小于最小正浮点数。介绍了IEEE 754的概念逐渐下溢denormal数字。在2008年修订标准改变了他们的名字低于正常的

认为舍入的数字接近下溢。在754年之前浮点数有令人不安的属性xy可能是不平等的,但他们的差异下溢x - y就变成了0。有754的差距0最小正浮点数充满数字的间隔之间的间距是一样的吗最小正浮点数2 *最小正浮点数。我喜欢称之为间距和最小的低能的号码,

小=最小正浮点数。*每股收益
小= 0.015625 5.9605 e-08 1.4013 e-45 4.9407 e - 324

浮点数的整数

flintmax

可以做整数和浮点数算术。我喜欢叫这样的数字燧石。当我们写数字3和3.0美元美元,它们是不同的描述相同的整数,但我们认为一个定点,另一个浮点数。最大的弗林特是flintmax

flintmax = 2. /每股收益
flintmax = 32 2048 1.6777 e + 07年9.0072 e + 15

技术上所有的浮点数比flintmax是整数,但它们之间的间距比1大,所以不安全使用整数运算。只有整数值之间的浮点数0flintmax可以是硬伤。

让我们一起收集所有这些解剖特征在一个新的MATLAB

T = [w;p;问;b;每股收益;最大浮点数;最小正浮点数;微小的;flintmax];T =表(T (: 1), T (:, 2), T (:, 3), T (:, 4),“variablenames”,{“季”,“一半”,“单一”,“双”},“rownames”,{' w ',“p”,“问”,“b”,“每股收益”,“最大浮点数”,“最小正浮点数”,“小”,“flintmax”});disp (T)
季度一半单一双________ __________ __________ ___________ w 8 16 32 64 p 4 10 23 52问3 5 8 11 b 3 15 127 1023年每股收益0.0625 0.00097656 1.1921 2.2204 e-07 e-16最大浮点数15.5 65504 3.4028 e+38 1.7977 e + 308最小正浮点数0.25 - 6.1035 e-05 1.1755 38吗2.2251 e - 308小0.015625 5.9605 1.4013 e-08 e-45 4.9407 e - 324 flintmax 32 2048 1.6777 e + 07年9.0072 e + 15

fp8和fp16

3.1版本的克里夫的实验室包括对象的代码@fp8@fp16开始提供完整quarter-precision和half-precision运算的实现。

目前提供的方法

方法(fp16)
方法类fp16: abs eps isfinite mrdivide rem subsref二进制eq le mtimes轮圣言ctranspose修复lt ne签下三角阵诊断接头fp16陆标准单一triu disp ge max +大小uminus显示gt -最大浮点数subsasgn双十六进制mldivide最小正浮点数subsindex

这些只提供部分的实现,因为算术不是在紧凑的形式。我们欺骗。为每个单独的标量操作,操作数被打开的短期存储到老式的双打。然后操作是由现有的双精度代码和结果返回到短格式。这个模拟精度降低和限制范围,但需要相对较少的新代码。

所有的工作都是在构造函数中@fp8 / fp8.m@fp16 / fp16.m我们可以称之为“拆解”@fp8 / double.m@fp16 / double.m。构造函数转换普通浮点数精度表示减少了包装尽可能多的32或64位将适合8或16位字。开箱的拆解做相反的事。

一旦这些方法可用,几乎一切都微不足道。大多数操作的代码是这样的重载。

类型@fp16 / plus.m
函数z = + (x, y) z = fp16(双(x) +双(y));结束

维基百科测试套件

维基百科页面关于half-precision包括几个16位的例子与符号,指数和部分字段分开。我已经添加了一些。

0 0 01111 0000000000 = 00101 0000000000 = 2 ^ -10 =每股收益0 01111 0000000000 = 1 +每股收益= 1.0009765625(1)最小的浮动之后下一个1 10000 0000000000 = 2 0 11110 0000000000 = 65504 (max半精密)= 2 ^ 15 * (2-eps) 0 00001 0000000000 = 2 ^ -14 = r ~ 6.10352 e-5(最小正正常)0 00000 1111111111 = r * (1-eps) ~ 6.09756 e-5(最大弱智者)0 00000 0000000001 = r * eps ~ 5.96046 e-8(最小正弱智者)0 00000 0000000000 ~ r * eps / 2(下溢于零)0 00000 0000000000 = 0 1 0 0 11111 00000 0000000000 = 0000000000 =∞1 11111 0000000000 =无穷大0 11111 01101 =南0 1111111111 0101010101 = 0.333251953125 ~ 1/3

这提供了检查我的测试套件fp16标量的操作。

明确0 = fp16 (0);一个= fp16 (1);每股收益=每股收益(一);r =最小正浮点数(一);测试= {' 1 ',“每股收益”,“1 +每股收益”,' 2 ',2 / r * (2-eps)”,“r”,“r * (1-eps)”,“r *每股收益”,的r * eps / 2,“零”,“零”,“1 /零”,“1 /零”,“零/零”,1/3的};

让我们运行测试。

t =测试(:)“x = eval (t {:});y = fp16 (x);z =二进制(y);w =双(y);流(% 18岁% 04年代% 19.10 g % 19.10 g % s \ n”,z,十六进制(y),双(x), w t {:})结束
0 01111 0000000000 3 c00 1 1 1 0 00101 0000000000 1400 0.0009765625 0.0009765625 eps 0 01111 0000000000 3 c01 1.000976563 1.000976563 1 +每股收益1 10000 0000000000 C000 2 2 2 0 11110 0000000000 7 bff 65504 65504 2 / r * (2-eps) 0 00001 0000000000 0400 6.103515625 6.103515625 e-05 e-05 r 0 6.097555161 6.097555161 00000 1111111111 03 ff e-05 e-05 r * (1-eps) 0 00000 0000000001 0001 5.960464478 5.960464478 e-08 e-08 r * eps 0 00000 0000000001 0001 5.960464478 5.960464478 e-08 e-08 r * eps / 2 0 00000 0000000000 0000 0 0 0 0 0 0 0 0 11111 00000 0000000000 0000 0000000000 7 c00正正1 / 0 1 11111 0000000000 FC00负负1 / 0 1 11111 1111111111 FFFF南南零/ 0 0 01101 0101010101 3555 0.3333333333 0.3332519531 1/3

矩阵运算

大部分的方法@fp8@fp16处理矩阵。的4×4幻方杜勒的忧郁症II提供了我的第一个例子。

清除格式shortgydF4y2BaM = fp16(魔法(4))
M = 16 2 3 13 5 11 10 8 9 7 6 12 4 14 15 1

让我们来看看这个拥挤的16位元素在二进制。

B =二进制(M)
B = 4×4字符串数组列1到3“0 10011 0000000000”“0 10000 0000000000”“0 10000 1000000000”“0 10001 0100000000”“0 10010 0110000000”“0 10010 0100000000”“0 10010 0010000000”“0 10001 1100000000”“0 10001 1000000000”“0 10001 0000000000”“0 10010 1100000000”“0 10010 1110000000”列4“0 10010 1010000000”“0 10010 0000000000”“0 10010 1000000000”“0 01111 0000000000”

检查行金额都是平等的。这个矩阵向量乘法可以做到完全的燧石幻方。

e = fp16(的(4,1))我= M * e
e = 1 1 1 1我= 34 34 34

fp16反斜杠

我已经超载mldivide,所以我可以解决线性系统和计算逆。实际的计算是通过lutx“教科书”功能,我写了年前,早在这half-precision项目。但是现在MATLAB对象系统确保每个人打开完成算术运算fp16数字。

让我们生成一个随机两位数整数5-by-5矩阵的条目。

一个= fp16 (randi (100 5 5))
44 49 = 76 71 83 75 4 70 39 45 40 28 32 77 65 66 96 80 71 10 4 19 76

我要使用fp16反斜杠,反一个。所以我需要一半的单位矩阵的精度。

我= fp16(眼(5))
I = 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1

现在,重载的反斜杠lutx计算逆。

X = \我
X = -0.0044 0.0346 0.0125 -0.0254 -0.0046 0.0140 -0.0116 0.0026 -0.0046 -0.0002 0.0071 -0.0176 -0.0200 0.0238 0.0008 -0.0060 -0.0020 0.0200 0.0006 -0.0125 0.0003 -0.0052 -0.0072 0.0052 0.0174

计算剩余。

AX = * X R =我- AX
AX = 1.0000 -0.0011 -0.0002 -0.0007 -0.0001 -0.0001 0.9990 -0.0001 -0.0007 -0.0001 -0.0001 -0.0005 1.0000 -0.0003 -0.0002 -0.0002 -0.0011 -0.0001 0.9995 -0.0002 -0.0000 -0.0001 0.0001 -0.0001 - 1.0000 0.0011 - 0.0002 R = 0 0 0.0007 0.0001 0.0001 0.0010 0.0001 0.0007 0.0001 0.0001 0.0005 0.0003 0.0002 0.0002 0.0011 0.0001 0.0005 0.0002 0.0000 0.0001 -0.0001 0.0001 0

这两个斧头R是我希望从算术是准确的只有三个小数位数。

虽然我得到不同的随机的一个每次我发表这篇博客,我希望它有一个温和的条件数。

kappa =电导率(A)
k = 15.7828

一个不是严重的条件,我可以转化计算逆和期望接近原来的整数矩阵。

Z = X \我
Z = 76.1250 71.0000 83.1250 44.1250 49.1250 75.1250 4.0234 70.1875 39.1250 45.1250 40.0625 28.0000 32.0625 77.0000 65.0625 66.1250 5.0234 96.1875 80.1250 71.1250 18.0156 10.0000 4.0156 19.0156 76.0000

fp16圣言

我刚刚若无其事的计算气孔导度(A)。但气孔导度不是在过载的方法的列表fp16。我很惊喜地发现matlab \ matfun \ cond.m安静地在这个新的数据类型。这是代码的核心。

dbtype气孔导度34:43,dbtype气孔导度47
34如果p = = 2 35 s =圣言();36若(s = = 0) %处理奇异矩阵37 c =正(类(A));其他38 39 c = max (s) /分钟(s);40如果isempty (c) 41 c = 0(类(A));42结束43结束47

所以正确使用奇异值分解,和我圣言会过载。圣言会计算是由一个433 m文件,svdtx,,就像lutx之前,写fp16存在。

让我们再次计算计算。

[U, V] =圣言(A)
U = -0.5210 -0.4841 0.6802 -0.0315 0.1729 -0.4260 -0.2449 -0.3572 -0.4561 -0.6504 -0.4058 0.4683 0.1633 0.6284 -0.4409 -0.5786 0.0268 -0.5620 0.1532 0.5703 -0.2174 0.6968 0.2593 -0.6104 0.1658 267.5000 S = 0 0 0 0 0 71.1875 55.5000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 37.3750 16.9531 V = -0.4858 -0.3108 -0.0175 -0.3306 -0.7471 -0.2063 -0.2128 0.9238 0.2195 0.1039 -0.5332 -0.5205 -0.2920 -0.0591 0.5967 -0.4534 0.2891 -0.2050 0.7993 -0.1742 -0.4812 0.7095 0.1384 -0.4478 0.2126

重建一个从它的精密计算的一半。这不是太寒酸。

USVT = U * * V '
USVT = 75.9375 71.0000 83.0625 44.0313 49.0000 75.0000 4.0117 70.0625 38.9688 45.0000 40.0313 28.0469 32.0313 77.0625 65.0625 66.0000 4.9688 96.0625 80.0000 71.0000 18.0313 10.0234 4.0156 19.0313 76.0000

最后,确认我们已经工作这么长时间fp16对象。

类属性名称大小字节226 5 x5 fp16 AX 5 x5 226 fp16 B 4 x4 1576弦我5 x5 226 fp16 184 4 x4 208 fp16我4 x1 fp16 R 5 x5 fp16 226年代5 x5 226 fp16 U 5 x5 226 fp16 USVT 5 x5 226 fp16 V 5 x5 226 fp16 X 5 x5 226 fp16 Z 5 x5 226 fp16 e 4 x1 184 fp16 kappa 1 x1 8双

计算器

我介绍一个计算器在我的博客上罗马数字。3.1版本的克里夫的实验室还包括一个豪华版的计算器计算,四个不同的精度,季度一半,单身,和双——并将结果显示在四个不同的格式——十进制、十六进制、二进制和罗马。

我喜欢展示计算器通过单击键

1 0 0 1 = 0/8

因为小数点扩张是一个重复.123456790

谢谢

由于MathWorkers本Tordoff史蒂夫·埃丁和Kiran Kintali提供背景和指针工作精度的一半。




发表与MATLAB®R2017a

|

评论

留下你的评论,请点击在这里MathWorks账户登录或创建一个新的。