浮点运算 (FLOP) 的定义是什么

What is the definition of Floating Point Operations ( FLOPs )

我正在尝试使用 SIMD(在 ARM CPU 上)优化我的代码,并想知道它的算术强度(flops/byte、AI)和 FLOPS。

为了计算AI和FLOPS,我必须计算浮点运算(FLOPs)的数量。 但是,我找不到任何关于 FLOPs 的精确定义。
当然,muladdsubdiv显然是FLOPs,但是move操作、shuffle操作(如_mm_shuffle_ps)、set操作(例如_mm_set1_ps),转换操作(例如_mm_cvtps_pi32)等?
它们是处理浮点值的操作。我应该把它们算作失败吗?如果不是,为什么?
像 Intel VTune 和 Nvidia 的 nvprof 或 PMU 这样的分析器通常会计算哪些操作?

编辑:

这道题主要是数学上复杂的运算。
我还想知道处理以浮点值或向量作为输入的 "not mathematical" 运算的标准方法。

随机播放/混合 FP 值不被视为 FLOP。它们只是在非纯粹的“垂直”问题上使用 SIMD 的开销,或者对于您使用混合无分支地进行的分支问题。

FP 也不是 AND/OR/XOR。您可以尝试使用 andps (_mm_and_ps) 来证明计算 FP 绝对值的合理性,但通常不会计算在内。 FP abs 不需要查看指数/尾数,或者对结果进行归一化,或者任何使 FP 执行单元变得昂贵的事情。 abs (AND) / sign-flip (XOR) 或 make negative (OR) 是微不足道的按位操作。


FMA 通常算作两个浮点运算(mul 和 add),即使它是与 SIMD FP add 或 具有相同(或相似)性能的单个指令多。 raw 上最重要的瓶颈问题 FLOP/s 是 matmul,它确实需要 mul 和 add 的等量混合,并且可以完美地利用 FMA。

所以 Haswell 核心的 FLOP/s 是

  • 其 SIMD 向量宽度(每个向量 8 float 个元素)
  • 每个时钟
  • 次 SIMD FMA (2)
  • 每个 FMA 的 FLOPs (2)
  • 倍时钟速度(它可以维持最大单核涡轮增压,同时最大化两个 FMA 单元;长期取决于冷却,短期仅取决于功率限制)。

对于整个 CPU,而不仅仅是单个内核:乘以内核数并使用最大持续时钟速度,所有内核都处于忙碌状态,通常低于 CPU 上的单核 Turbo根本没有涡轮增压。)

英特尔和其他 CPU 供应商没有考虑到他们的 CPU 也可以维持 vandps 与每个时钟 2 vfma132ps 指令并行,因为FP abs不是什么难的操作

另见 How do I achieve the theoretical maximum of 4 FLOPs per cycle?。 (在现代 CPUs :P 上实际上超过 4 个)


如果您有很多其他开销占用前端带宽或造成其他瓶颈,则无法实现峰值 FLOPS(每秒 FP 操作数,或 FLOP/s)。该指标只是您在 运行 直线上可以做的原始数学量,而不是任何特定的实际问题。

虽然人们会认为如果理论上的峰值触发器比精心手动调整的 matmul 或 Mandelbrot 可以达到的高得多,即使对于编译时常数问题大小也是如此,这很愚蠢。例如如果前端跟不上做任何商店以及 FMA。例如如果 Haswell 有四个 FMA 执行单元,那么它只能在每条指令都是 FMA 的情况下维持最大的 FLOPs。内存源操作数可以微融合加载,但在不影响吞吐量的情况下没有存储空间。

Intel 甚至没有 3 个 FMA 单元的原因是大多数实际代码都难以饱和 2 个 FMA 单元,尤其是只有 2 个加载端口和 1 个存储端口。它们几乎所有时间都会被浪费掉,而且 256 位 FMA 单元需要很多晶体管。

(Ice Lake 将流水线的 issue/rename 阶段扩展到 5 uops/clock,但也使用 AVX-512 将 SIMD 执行单元扩展到 512 位,而不是添加第 3 个 256 位 FMA 单元. 它有 2/clock 加载 2/clock store,尽管对于 32 字节或更窄的存储,存储吞吐量只能持续到 L1d 缓存,而不是 64 字节。)

在优化方面,通常的做法是仅在代码的 热点 上测量 FLOP,例如,卷积中浮点乘法和累加运算的数量.这主要是因为其他操作可能微不足道或不可替代,因此不能用于任何类型的优化。

例如,ARMv7 Reference Manual 中 A4.13 中向量浮点指令下的所有指令都属于浮点运算,因为 FPU 指令的 FLOPs/Cycle 在处理器中通常是常量。

不仅是 ARM,许多微处理器都有专用的浮点单元,因此当您测量 FLOP 时,您就是在测量该单元的速度。有了这个和 FLOPs/cycle 你可以或多或少地计算出理论峰值性能。

但是,要对 FLOP 持保留态度,因为它们只能用于粗略估计代码的速度,因为它们没有考虑处理器运行的其他条件。这就是为什么在大多数情况下只为热点(通常是算术运算)计算 FLOPs 就足够了。

话虽如此,FLOP 可以作为两个费力代码的比较指标,但并不能说明您的代码本身。