深度学习等计算密集型任务很关注设备的峰值算力,落实到具体指标,就是大家都很关心 T(FL)OPS(Tera (FLoat) OPerations per Second)
。这里,operations 具体指的就是乘加操作。该指标在 GPU 上是明确标示供查的,但 CPU 目前并不会在 spec 中暴露 T(FL)OPS
指标。
一种方法可以通过跑 BLAS 的 benchmark 来测量的,这种方法有两个问题:一是需要一定的操作成本,二是受软件优化的影响(所以,如果出了问题就容易不知道这是硬件能力不行还是软件优化没到位)。因此,需要一个对硬件能力的直接估计。
这里提供一个计算 CPU 峰值算力的公式来解决这个问题。
CPU 使用 SIMD 协处理器(co-processor)来加速 FP32 乘加运算,如 SSE、AVX2、AVX512。更具体地,是由协处理器的 FMA(Fused Multiply-Add)
单元完成的。所以 CPU 的 T(FL)OPS
主要取决于 FMA
的计算能力。
FP64 FMA 乘加指令 vfmadd132pd
执行以下操作:
这里,向量的长度由 AVX 寄存器长度决定。
如: 一个 AVX512 寄存器可以存放 8 个 FP64($512\ bits\ /\ (8 \times 8) = 8$)那么
因此,FP64 的
这里,乘法和加法各算一个操作,所以 8 需要乘 2。
Xeon SkyLake 8180,一个 socket 有 28 个 core,每个 core 有一个AVX512 协处理器,每个 AVX512 协处理器配有 2 个 FMA。因此:
frequency 可以通过查 spec 得到,这里需要取 AVX512 max all core Turbo frequency,即 2.3 GHz。
所以,一个双路(dual-socket)SkyLake 8180 系统的 FP64 峰值 TFLOPS
为:
FP32 FMA 乘加指令 vfmadd132ps
执行以下操作:
一个 AVX512 寄存器可以存放 16 个 FP32($512\ bits\ /\ (8 \times 4) = 16$),因此
因此,FP32 的
Xeon SkyLake 8180,一个 socket 有 28 个 core,每个 core 有一个 AVX512 协处理器,每个 AVX512 协处理器配有 2 个 FMA。因此:
又因为 8180 AVX-512 max all core Turbo frequency = 2.3GHz,则一个双路 SkyLake 8180 系统的 FP32 峰值 TFLOPS 为:
Xeon CPU 在 SapphirRapids(SPR)之前不支持 FP16 的原生 FMA 运算,需要先通过 vcvtph2ps
指令将 FP16 转换成 FP32,再通过 FP32 的 FMA 运算来完成。此时,FP16 的峰值 TFLOPS 与 FP32 的峰值 TFLOPS 是相等的。
从 SPR 开始,AVX512 引入了 vfmadd132ph
指令用于 FP16 的 FMA 运算。凡是 CPU Flag 中有 AVX512_FP16
的 CPU 均支持原生 FP16乘加。一个 AVX512 寄存器可以存放 32 个 FP16($512\ bits\ /\ (8 \times 2) = 32$),一个 AVX512 FMA 每个 clock cycle 可以做 32 个乘加操作,如下:
此时,FP16 的
Xeon CPU 从 CooperLake(CPX)开始支持 BF16 的乘加运算,凡是 CPU Flag 中有 AVX512_BF16
的 CPU 均支持原生 BF16 乘加。但因为其复用了 FP32 的 FMA,所以暴露出来的 BF16 指令并不是标准的 FMA,而是 DP(Dot Product)。
BF16 DP 指令 vdpbf16ps
操作如下:
一个 AVX512 寄存器可以存放 32 个 BF16($512\ bits\ /\ (8 \times 2) = 32$)。因此,一个 AVX512 BF16 DP 每个 clock cycle 可以做 32 个乘加操作。
因此,$operations_per_cycle$ 可以计算如下:
CPU 通过两条指令 vpmuldq + vpaddq
完成 INT32 的乘加操作,如下:
一个 AVX512 寄存器可以存放 16 个 INT32($512\ bits\ /\ (8 \times 4) = 16$)。因此,一个 AVX512 FMA 每 2 个 clock cycle 可以做 16 个 INT32 乘加操作,即平均每个 clock cycle 可以做 8 个 INT32 乘加操作。
因此,$operations_per_cycle$ 可以计算如下:
在支持VNNI(Vector Neural Network Instructions)指令前,CPU 通过两条指令 vpmaddwd + vpaddd
完成 INT16 的 DP 操作(原因也是为了复用 INT32 的 FMA,所以选择不支持 INT16 的 FMA,而只支持 Multiply Add),如下:
一个 AVX512 寄存器可以存放 32 个 INT16($512\ bits\ /\ (8 \times 2) = 32$)。因此,每 2 个 clock cycle 可以做 32 个 INT16 乘加操作,即平均每个 clock cycle 做 16 个 INT16 乘加操作。
因此,$operations_per_cycle$ 可以计算如下:
在支持 VNNI 指令后,CPU 通过一条指令 vpdpwssd
完成 INT16 的乘加操作,如下:
因此,一个 AVX512 FMA 每个 clock cycle 可以做 32 个 INT16 乘加操作,$operations_per_cycle$ 可以计算如下:
在支持 VNNI 指令前,CPU 通过三条指令 vpmaddubsw + vpmaddwd + vpaddd
完成 INT8 的 DP 操作,如下:
一个 AVX512 寄存器可以存放 64 个 INT8($512\ bits\ /\ (8 \times 1) = 64$)。因此,一个 AVX512 FMA 每 3 个 clock 可以做 64 个 INT8 乘加操作,即平均每个 clock 做
因此,$operations_per_cycle$ 可以计算如下:
在支持 VNNI 指令后,CPU 通过一条指令 vpdpbusd
完成 INT8 的 DP 操作,如下:
一个 AVX512 寄存器可以存放 64 个 INT8($512\ bits\ /\ (8 \times 1) = 64$)。因此,一个 AVX512 FMA 每个 clock cycle 可以做 64 个 INT8 乘加操作。
因此,$operations_per_cycle$ 可以计算如下: