代码之家  ›  专栏  ›  技术社区  ›  Kadir

Intel芯片上的半精度浮点算法

  •  15
  • Kadir  · 技术社区  · 7 年前

    是否可以在英特尔芯片上执行半精度浮点运算?

    我知道如何加载/存储/转换半精度浮点数,但我不知道如何在不转换为单精度浮点数的情况下进行加法/乘法。

    [1] https://software.intel.com/en-us/articles/performance-benefits-of-half-precision-floats

    2 回复  |  直到 6 年前
        1
  •  30
  •   Peter Cordes    3 年前

    相关: https://scicomp.stackexchange.com/questions/35187/is-half-precision-supported-by-modern-architecture -有一些关于库珀湖和蓝宝石激流中BFloat16的信息,还有一些非英特尔信息。

    Sapphire Rapids将拥有两个BF16 FP16 ,FP16使用相同的IEEE754 binary16 格式为F16C转换指令,而不是脑浮点数。和 AVX512-FP16 支持大多数数学运算,与BF16不同,BF16只支持从单精度和点积累加对到单精度的转换。

    这也适用于Alder Lake系统,该系统在BIOS中禁用了E cores并专门启用了AVX-512(其中 apparently isn't officially supported 截至目前;只有一些mobo供应商有此选项。)

    (对于具有FP16/BF16的蓝宝石激流/桤木湖,其余答案未更新。)


    使用片上GPU

    是否可以在英特尔芯片上执行半精度浮点运算?

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

    在早期的芯片上,FP16和FP32的吞吐量大致相同(可能只是在运行中进行转换,几乎是免费的),但是 on SKL / KBL chips you get about double the throughput of FP32 对于GPGPU Mandelbrot (请注意该链接中图表Mpix/s轴上的对数刻度)。

    FP64中的增益( double )在Skylake iGPU上的表现也很出色。


    使用AVX/AVX-512指令

    但是 在IA核心上(英特尔体系结构)否 ;即使使用AVX512,也没有任何硬件支持,只能将其转换为单精度。这可以节省内存带宽,并且如果代码在内存上出现瓶颈,肯定可以加快速度。但对于内存没有瓶颈的代码,它在峰值失败时不会增加。

    当然,您可以实现软件浮点,甚至可能在SIMD寄存器中实现,因此从技术上来说,对于您提出的问题,答案仍然是“是”,但不会比使用F16C更快 VCVTPH2PS / VCVTPS2PH 说明书+单件包装 vmulps / vfmadd132ps 硬件支持。

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


    即将推出: bfloat16 (Brain Float) 和AVX512 BF16

    为神经网络用例开发了一种新的16位FP格式,其指数范围与IEEE binary32相同。与IEEE binary16(如x86 F16C)转换指令相比,它的有效位精度要低得多,但显然神经网络代码更关心大指数范围内的动态范围。这使得bfloat硬件甚至不必为支持次正常值而烦恼。

    一些即将推出的Intel x86 CPU内核将具有支持此格式的硬件。主要用例仍然是专用的神经网络加速器( Nervana )和GPGPU类型的设备,但硬件支持的转换至少是非常有用的。

    https://en.wikichip.org/wiki/brain_floating-point_format 有更多细节, 特别是 Cooper Lake Xeon和Core X CPU预计将支持 AVX512 BF16

    我还没有看到关于冰湖(Sunny Cove Microach)的报道。我不想猜测,这两种情况都有可能发生。

    Intel® Architecture Instruction Set Extensions and Future Features Programming Reference 2019年4月的修订版-036增加了BF16的详细信息,包括它被定为“未来,库珀湖”。一旦发布,说明文档将移至主卷2 ISA ref手册(以及pdf->HTML摘要 https://www.felixcloutier.com/x86/index.html )。

    https://github.com/HJLebbink/asm-dude/wiki 有vol.2和future extensions手册中的说明,因此您可以在那里找到它。

    只有3条说明:转换到/从 浮动 ,和BF16乘法+成对累加到 浮动 (点积的第一个水平步骤。)So AVX512 BF16 最后,为16位浮点提供真正的计算,但仅以这种非常有限的形式将结果转换为 浮动

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

    另外两个不支持内存故障抑制(对内存源操作数使用掩蔽时)。大概是因为屏蔽是针对每个目标元素的,并且源元素的数量不同。转变 BF16显然可以抑制内存故障,因为相同的掩码可以应用于32位源元素和16位目标元素。

    • VCVTNE2PS2BF16 [xyz]mm1{k1}{z}, [xyz]mm2, [xyz]mm3/m512/m32bcst
      将压缩单2的2个寄存器(无例外)转换为BF16。
      _m512bh _mm512_cvtne2ps_pbh (__m512, __m512);

    • VDPBF16PS [xyz]mm1{k1}{z}, [xyz]mm2, [xyz]mm3/m512/m32bcst
      BF16对点积累加成压缩单精度
      __m512 _mm512_dpbf16_ps(__m512, __m512bh, __m512bh); (请注意,即使是无掩码版本,目标累加器也有第三个输入,如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的符号/指数/有效位的固定宽度字段结构。越来越受欢迎的是 假定 https://en.wikipedia.org/wiki/Unum_(number_format) ,则, Beating Floating Point at its Own Game: Posit Arithmetic https://posithub.org/about

    他们没有将整个有效位编码空间花费在NAN上,而是将其用于锥形/渐变溢出,支持更大的范围。(删除NaN简化了硬件)。IEEE浮动仅支持渐进式 底流,底流 (低于正常值),硬溢出到+-Inf。(这通常是真实数值模拟中的错误/问题,与NaN没有太大区别。)

    The Posit encoding 是一种可变宽度指数,精度更高,接近1.0。目标是允许在更多情况下使用32位或16位精度(而不是64位或32位),同时仍能获得科学计算/高性能计算的有用结果,如气候建模。将每个SIMD向量的工作量加倍,内存带宽减半。

    已经有一些针对Posite FPU硬件的纸上设计,但这还为时尚早,我认为只有FPGA实现才真正建成。一些Intel CPU将附带板载FPGA(或者这已经是一件事了)。

    截至2019年年中,我还没有读到任何作为商业CPU设计一部分的Posit执行单元,谷歌也没有发现任何东西。

        2
  •  3
  •   Avatar    5 年前

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

    推荐文章