Sandy Bridge和Haswell SSE2/AVX/AVX2每个时钟周期的FLOPS

60
我对Sandy-Bridge和Haswell每个核心每周期可以完成多少Flops感到困惑。
据我所知,使用SSE应该是每个核心每个周期4个Flops,而使用AVX/AVX2应该是每个核心每个周期8个Flops。
这在以下链接中得到了验证, 如何达到每个周期的理论最大值4 FLOPs? 以及这里, Sandy-Bridge CPU规格
然而下面的链接似乎表明Sandy-Bridge每个核心每个周期可以完成16 Flops,而Haswell是32 Flops。 http://www.extremetech.com/computing/136219-intels-haswell-is-an-unprecedented-threat-to-nvidia-amd
有人能解释一下吗?
编辑: 我现在明白为什么我感到困惑了。 我认为术语FLOP只指单精度浮点数(SP)。 我现在看到,在如何达到每个周期的理论最大值4 FLOPs?中的测试实际上是双精度浮点数(DP),因此他们实现了每个周期4 DP FLOPs(对于SSE)和8 DP FLOPs/cycle(对于AVX)。 重新在SP上进行这些测试将是有趣的。

1
针对您的编辑:这些数字将恰好是 DP 数字的两倍。这是因为 SP 和 DP 版本的 SIMD 指令的延迟和吞吐量是相同的。(在某些情况下,SP 版本甚至具有更低的延迟。) - Mysticial
我已经尽力将代码转换为使用SP,并在Visual Studio 2012中进行了编译。然而,我没有看到速度上的差异,而且总和报告了一个错误,所以很可能我需要改变更多的代码。我得回头再看看这个问题。 - user2088790
你需要将数字翻倍,因为计数器假定DP。(将48 * 1000 * iterations * tds * 2更改为48 * 1000 * iterations * tds * 4)此外,你需要更改重新规范化掩码以在SP上工作:uint64 iMASK = 0x800fffffffffffffull; - Mysticial
由于每个SSE寄存器可以容纳四个SP浮点数,因此结果为4。再次感谢您。我还将重新规范化掩码更改为无符号整数iMASK = 0x80fffffu。现在它可以正常工作,并且像您说的那样获得了两倍的效果。 - user2088790
2个回答

123
以下是一些最新处理器微架构的理论最大 FLOPs 数量(每个核心),以及如何实现它们的说明。
通常,要计算这个值,请查找 FMA 指令的吞吐量,例如在https://agner.org/optimize/或任何其他微基准测试结果中,然后乘以 (FMA 每时钟周期数) * (向量元素 / 指令) * 2 (FLOPs / FMA)。
请注意,要在实际代码中实现这一点需要非常谨慎的调整(如循环展开),并且需要几乎零的缓存缺失率以及没有其他任何瓶颈。现代 CPU 具有如此高的 FMA 吞吐量,以至于其他指令存储结果或用输入提供结果的空间有限。例如,在大多数 x86 CPU 上,每时钟周期最多只能进行 2 个 SIMD 加载,因此点积会在每 1 个 FMA 的 2 个加载上出现瓶颈。虽然如此,经过精心调整的密集矩阵乘法可以接近实现这些数字。
如果你的工作负载包括任何无法合并为FMA的ADD/SUB或MUL操作,则理论上的最大值不是你的工作负载的适当目标。Haswell/Broadwell每个时钟周期有2个SIMD FP乘法(在FMA单元上),但每个时钟周期只有1个SIMD FP加法(在具有较低延迟的单独向量FP加法器上)。Skylake放弃了单独的SIMD FP加法器,使任何向量宽度的add/mul/fma在4c延迟、每时钟周期2次吞吐量下运行相同。

英特尔

请注意,最近微架构的赛扬/奔腾版本不支持AVX或FMA指令,只支持SSE4.2。

英特尔Core 2和Nehalem(SSE/SSE2):

  • 每个周期4个DP FLOPs:2个宽度为2的SSE2加法+2个宽度为2的SSE2乘法
  • 每个周期8个SP FLOPs:4个宽度为4的SSE加法+4个宽度为4的SSE乘法

英特尔Sandy Bridge/Ivy Bridge(AVX1):

  • 每个周期8 DP FLOPs:4个宽度为4的AVX加法+4个宽度为4的AVX乘法
  • 每个周期16 SP FLOPs:8个宽度为8的AVX加法+8个宽度为8的AVX乘法

Intel Haswell/Broadwell/Skylake/Kaby Lake/Coffee/... (AVX+FMA3):

  • 每个周期16 DP FLOPs:两个宽度为4的FMA(融合乘加)指令
  • 每个周期32 SP FLOPs:两个宽度为8的FMA(融合乘加)指令
  • (使用256位向量指令可能会降低某些CPU的最大睿频时钟速度。)

Intel Skylake-X/Skylake-EP/Cascade Lake等(AVX512F),带有1个FMA单元:某些Xeon Bronze/Silver

  • 每个周期16 DP FLOPs:一个8位宽的FMA(融合乘加)指令
  • 每个周期32 SP FLOPs:一个16位宽的FMA(融合乘加)指令
  • 与更窄的256位指令相同的计算吞吐量,但可以通过AVX512实现更宽的加载/存储、一些不运行在FMA单元上的向量操作和更宽的洗牌来实现速度提升。
  • (同时有512位向量指令的情况下会关闭端口1上的向量ALU。此外,会降低最大睿频时钟速度,因此“周期”不是您性能计算中的常数。)

Intel Skylake-X/Skylake-EP/Cascade Lake等(AVX512F),配备2个FMA单元:Xeon Gold/Platinum以及i7/i9高端台式机(HEDT)芯片。

  • 每个周期32 DP FLOPs:两个8位FMA(融合乘加)指令
  • 每个周期64 SP FLOPs:两个16位FMA(融合乘加)指令
  • (在执行512位向量指令时,将关闭端口1上的向量ALU。还会降低最大睿频时钟速度。)

未来:预计Intel Cooper Lake(Cascade Lake的后继者)将引入Brain Float,这是一种针对神经网络工作负载的float16格式,并支持实际的SIMD计算,而不像当前的F16C扩展只支持转换为float32的加载/存储。这应该可以将与单精度相同硬件的FLOP /周期吞吐量翻倍。

当前的Intel芯片只能在iGPU上直接对标准float16进行实际计算。


AMD

AMD K10:

  • 每个周期4个DP浮点数操作:2个宽度为SSE2的加法+2个宽度为SSE2的乘法
  • 每个周期8个SP浮点数操作:4个宽度为SSE的加法+4个宽度为SSE的乘法

AMD Bulldozer/Piledriver/Steamroller/Excavator,每个模块(两个核心):

  • 每个周期8个DP浮点数操作:4个宽度为FMA
  • 每个周期16个SP浮点数操作:8个宽度为FMA

AMD Ryzen

  • 每个周期8个DP浮点数操作:4个宽度为FMA
  • 每个周期16个SP浮点数操作:8个宽度为FMA

x86 低功耗

英特尔 Atom(Bonnell/45nm、Saltwell/32nm、Silvermont/22nm):

  • 每个周期1.5 DP FLOPs:标量SSE2加法+标量SSE2乘法
  • 每个周期6 SP FLOPs:4宽SSE加法+4宽SSE乘法

AMD Bobcat:

  • 每个周期1.5 DP FLOPs:标量SSE2加法+标量SSE2乘法
  • 每个周期4 SP FLOPs:4宽SSE加法+4宽SSE乘法

AMD Jaguar:

  • 每四个周期3 DP FLOPs:4宽AVX加法+4个周期的4宽AVX乘法
  • 每个周期8 SP FLOPs:8宽AVX加法+8宽AVX乘法


ARM

ARM Cortex-A9:

  • 每个周期1.5 DP FLOPs:标量加法+标量乘法
  • 每隔一个周期4个SP FLOPs:4个宽NEON加法+ 4个宽NEON乘法

ARM Cortex-A15:

  • 每个周期2 DP FLOPs:标量FMA或标量乘-加
  • 每隔一个周期8个SP FLOPs:4个宽NEONv2 FMA或4个宽NEON乘-加

Qualcomm Krait:

  • 每个周期2 DP FLOPs:标量FMA或标量乘-加
  • 每隔一个周期8个SP FLOPs:4个宽NEONv2 FMA或4个宽NEON乘-加

IBM POWER

IBM PowerPC A2 (Blue Gene/Q)每个核心:

  • 每个周期8个DP FLOPs:每个周期4宽QPX FMA
  • SP元素扩展到DP并在同一单元上处理

IBM PowerPC A2 (Blue Gene/Q)每个线程:

  • 每隔一个周期,4个DP FLOPs:每个周期4宽QPX FMA
  • SP元素扩展到DP并在同一单元上处理

Intel MIC / Xeon Phi

英特尔鲸鱼芯片(Knights Corner)每个核心:

  • 每一个周期16个双精度浮点运算:每个周期8个宽FMA
  • 每一个周期32个单精度浮点运算:每个周期16个宽FMA

英特尔鲸鱼芯片(Knights Corner)每个线程:

  • 每隔一个周期8个双精度浮点运算:每隔一个周期8个宽FMA
  • 每隔一个周期16个单精度浮点运算:每隔一个周期16个宽FMA

英特尔鲸鱼芯片(Knights Landing)每个核心:

  • 每个周期32个双精度浮点运算:每个周期两个8个宽FMA
  • 每个周期64个单精度浮点运算:每个周期两个16个宽FMA

IBM Blue Gene/Q和英特尔鲸鱼芯片(Knights Corner)有每个线程和每个核心的数据是因为这些核心在每个核心运行多个线程时具有更高的指令发出率。


3
在SSE2中添加了DP支持。 - Marat Dukhan
3
Cortex-M0和M3甚至没有FPU,因此它们每个周期都不执行任何FLOPs。即使在M4上,FPU也是可选的。Cortex-A8可以使用NEON每个周期执行2个SP FLOPs。双精度......好吧,在A8上,VFP没有经过流水线处理,因此每个周期大约只能执行1/8个DP FLOPs。 - Stephen Canon
3
他们是按模块计费的。 - Marat Dukhan
1
提供一些参考资料或解释如何获取这些信息会很有帮助。 - user842994
1
Skylake-X有1个或2个AVX512 FMA单元的配置... https://software.intel.com/en-us/forums/intel-isa-extensions/topic/737959 - michaf
显示剩余26条评论

21

在Haswell架构下,加法的吞吐量低于乘法和FMA。有两个乘法/FMA单元,但只有一个浮点数加法单元。如果您的代码主要包含加法,则必须使用具有1.0乘数的FMA指令替换加法才能获得最大吞吐量。

在Haswell上,FMA指令的延迟为5,吞吐量为每个时钟2次。这意味着您必须保持10个并行操作以获得最大吞吐量。例如,如果您想添加一个非常长的浮点数列表,则必须将其分成十个部分并使用十个累加器寄存器。

这确实是可能的,但是谁会为了一个特定的处理器进行这样奇怪的优化呢?


你不需要手动打破循环,只要进行一点编译器展开和乱序硬件(假设没有依赖关系),就可以让你达到相当大的吞吐量瓶颈。再加上超线程,每个时钟周期执行2个操作就变得非常必要了。 - Leeor
1
@Leeor,也许你可以发布一些代码来展示这个问题?使用FMA展开10次可以得到最佳结果。请参见我的回答:https://dev59.com/rmEi5IYBdhLWcg3wpdjJ#21600232 - Z boson
3
大多数计算密集型HPC代码(即flop-bound)都会执行大量的FMA运算。 根据我的经验,需要执行大量加法运算的地方往往是带宽瓶颈,因此增加加法吞吐量并不能提高性能。 - Jeff Hammond
2
最新的英特尔处理器代际具有更平衡的吞吐量。浮点加法、乘法和FMA指令的吞吐量均为每个时钟周期2条指令,延迟为4。 - A Fog

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