英译中:英特尔芯片上的半精度浮点运算

20
2个回答

34

相关: https://scicomp.stackexchange.com/questions/35187/is-half-precision-supported-by-modern-architecture - 关于Cooper Lake和Sapphire Rapids中的BFloat16以及一些非英特尔信息。

Sapphire Rapids将同时支持BF16和FP16,其中FP16使用与F16C转换指令相同的IEEE754二进制16格式,而不是brain-float。AVX512-FP16支持大多数数学运算,而BF16只有转换为/从单精度和点积累加对成单精度的功能。

这也适用于Alder Lake,在禁用E核并在BIOS中专门启用AVX-512的系统上(截至目前,显然还没有官方支持;只有一些主板厂商提供此选项)。

(答案的其余部分未更新,仍涉及Sapphire Rapids / Alder Lake具有FP16 / BF16的情况。)


使用芯片上的GPU

英特尔芯片是否支持半精度浮点运算?

是的,显然,Skylake及以后版本的芯片中的芯片上GPU硬件支持FP16和FP64,以及FP32。通过足够新的驱动程序,您可以通过OpenCL使用它。

在早期的芯片上,FP16与FP32的吞吐量大致相同(可能只是几乎免费地进行转换),但在SKL / KBL芯片上,GPGPU Mandelbrot的FP32吞吐量大约是FP32的两倍(请注意该链接中Mpix/s轴上的对数刻度)。

Skylake iGPU上FP64(double)性能的增益也非常巨大。


使用AVX / AVX-512指令

但是在IA核心(Intel-Architecture)上,甚至使用AVX512也没有硬件支持除将它们转换为单精度之外的任何内容。这可以节省内存带宽,并且如果您的代码瓶颈在内存上,则肯定可以加快速度。但是对于不受内存瓶颈限制的代码,它并不能增加峰值FLOPS。

当然,您可以实现软件浮点运算,可能甚至可以在SIMD寄存器中实现,因此从技术上讲,您提出的问题的答案仍然是“是”,但它不会比使用F16C VCVTPH2PS / VCVTPS2PH指令+打包单精度vmulps / vfmadd132ps硬件支持更快。

在x86代码中使用支持HW的SIMD转换以/从float / __m256来交换额外的ALU转换工作,以减少内存带宽和缓存占用。但是,如果缓存阻塞(例如针对经过良好调整的密集matmul)或非常高的计算强度意味着您没有内存瓶颈,则只需使用float并节省ALU操作。


即将到来的是:bfloat16 (Brain Float)和AVX512 BF16
为神经网络应用开发了一种新的16位FP格式,其指数范围与IEEE二进制32相同。与x86 F16C转换指令使用的IEEE二进制16相比,它具有更少的有效数字精度,但显然神经网络代码更关心大指数范围的动态范围。这使得bfloat硬件甚至不需要支持次规范。
一些即将推出的Intel x86 CPU核心将支持此格式的硬件。主要用例仍然是专用神经网络加速器(Nervana)和GPGPU类型设备,但硬件支持的转换至少非常有用。 https://en.wikichip.org/wiki/brain_floating-point_format有更多细节,特别是Cooper Lake Xeon和Core X CPU预计将支持AVX512 BF16
我没有看到它在Ice Lake(Sunny Cove微体系结构)中提到。这可能有两种情况,我不想猜测。

Intel®架构指令集扩展和未来功能编程参考在2019年4月的修订版-036中增加了有关BF16的详细信息,包括它被安排在“未来,库珀湖”中。一旦发布,指令的文档将移至主vol.2 ISA参考手册(以及pdf->HTML爬取https://www.felixcloutier.com/x86/index.html)。

https://github.com/HJLebbink/asm-dude/wiki具有来自vol.2和未来扩展手册的说明,因此您已经可以在那里找到它。

只有三条指令:转换为/从float,以及BF16乘法+成对累加到float。(点积的第一步水平)。因此,AVX512 BF16最终提供了真正的16位浮点计算,但仅以这种非常有限的形式将结果转换为float

他们还忽略MXCSR,始终使用默认舍入模式和DAZ / FTZ,并且不设置任何异常标志。

其他两个不支持内存错误抑制(使用掩码与内存源操作数一起使用时)。可能是因为掩码是针对目标元素的,而源元素数量不同。显然,将单精度浮点数转换为BF16可以抑制内存错误,因为相同的掩码可以适用于32位源元素和16位目标元素。

  • VCVTNE2PS2BF16 [xyz]mm1{k1}{z}, [xyz]mm2, [xyz]mm3/m512/m32bcst
    ConVerT (No Exceptions) 2 registers of Packed Single 2(to) BF16.
    _m512bh _mm512_cvtne2ps_pbh (__m512, __m512);

  • VDPBF16PS [xyz]mm1{k1}{z}, [xyz]mm2, [xyz]mm3/m512/m32bcst
    Dot Product of BF16 Pairs Accumulated into Packed Single Precision
    __m512 _mm512_dpbf16_ps(__m512, __m512bh, __m512bh); (Notice that even the unmasked version has a 3rd input for the destination accumulator, like an FMA).

      # the key part of the Operation section:
      t ← src2.dword[ i ]  (or  src.dword[0] for a broadcast memory source)
      srcdest.fp32[ i ] += make_fp32(src1.bfloat16[2*i+1]) * make_fp32(t.bfloat[1])
      srcdest.fp32[ i ] += make_fp32(src1.bfloat16[2*i+0]) * make_fp32(t.bfloat[0])
    

所以我们仍然没有得到本地的16位FP数学,您可以在保持数据为16位格式的情况下用于任意事物,每个向量32个元素。只有FMA进入32位累加器。


顺带一提,还有其他基于IEEE-754结构的实数格式之外的格式,用于符号/指数/尾数的固定宽度字段。其中一个日渐流行的是Posithttps://en.wikipedia.org/wiki/Unum_(number_format), 打败浮点运算:Posit算术, 和 https://posithub.org/about
不再将整个尾数编码空间用于NaN,而是将其用于锥形/逐渐溢出,支持更大的范围。(并且去除NaN简化了硬件)。IEEE浮点数仅支持逐渐下溢(使用亚规格),并具有硬上溢到+-Inf。(这通常是真实数值模拟中的错误/问题,与NaN没有太大区别。) Posit编码类似于可变宽度指数,在接近1.0的位置留下更多精度。目标是允许在更多情况下使用32位或16位精度(而不是64位或32位),同时仍然获得科学计算/高性能计算的有用结果,例如气候建模。每个SIMD向量的工作量加倍,内存带宽减半。

有一些关于Posit FPU硬件的论文设计,但现在还处于早期阶段,我认为只有FPGA实现已经被构建。一些Intel CPU将配备板载FPGA(或者可能已经是现成的东西)。

截至2019年中期,我没有看到任何商用CPU设计中包含Posit执行单元的报道,谷歌也没有找到任何相关信息。


2
@PeterCordes:有趣。Anandtech文章Intel文档表明,BF16只有转换指令和点积。 - wim
@bobcat:1. 这段话是在谈论iGPU。2. Sandybridge甚至不支持F16C扩展用于AVX转换到/从打包浮点数。3. 输入的软件转换=>矩阵乘法=>结果的软件转换可能不会像慢1000倍那么糟糕,因此对于缺乏硬件支持的情况而言,糟糕优化的软件显然使事情变得更加缓慢。 - Peter Cordes
据我所知,英特尔的集成显卡性能相对较弱。我在想,是否值得将其用于[gpgpu]计算。显然,MKL不支持它们 - MWB
即使使用了AVX512,也没有硬件支持除将它们转换为单精度之外的任何操作。奇怪的是...https://en.wikipedia.org/wiki/AVX-512列出了一堆FP16**算术**指令。 - MWB
@bobcat:当这个回答刚发布的时候,这是正确的。请记住,AVX-512并不是一个整体。他们不会使用像AVX-512-2这样的新数字来表示,而是使用像AVX-512VBMI或AVX-512FP16这样的新扩展名。Sapphire Rapids还没有发布,所以我应该抽出时间更新这个回答,加上那个非常新的扩展,它添加了本地FP16支持,感谢你提醒我。当我写这篇文章时,AVX-512BF16支持仍然是“即将到来”的/纸面上的,现在已经在Cooper Lake中发布了。如果您想编辑此答案,请随意提及即将推出的扩展名。 - Peter Cordes
显示剩余9条评论

4

如果您正在使用所有核心,我认为在许多情况下,您仍然受到内存带宽的限制,使用半精度浮点数将是一个优势。


是的,没错。也许我的回答没有表达得非常清楚,我会重新措辞一下。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接