我认为Agner的博客也提到了类似的问题(但我找不到确切的帖子)。 我想知道Skylake支持的其他指令是否有类似的影响,以后可能会降低功率来最大化吞吐量? 所有具有v前缀的指令(如
vmovapd
,vmulpd
,vaddpd
,vsubpd
,vfmadd213pd
)都是吗?我正在尝试编译一份在Xeon Skylake上运行时需要避免的C++应用程序指令列表。
vmovapd
,vmulpd
,vaddpd
,vsubpd
,vfmadd213pd
)都是吗? Width Light Heavy
--------- ------- -------
Scalar L0 N/A
128-bit L0 L0
256-bit L0 L1*
512-bit L1 L2*
*soft transition (see below)
ps
或pd
结尾,如addpd
),以及大部分以vpmul
或vpmad
开头的整数乘法指令,因为SIMD整数乘法实际上是在SIMD单元上运行的,还有vplzcnt(q|d)
也是在FMA单元上运行的。L1*
。这是因为这些指令在发生时会引起软过渡。另一个L1条目(针对512位轻指令)会引起硬过渡。在这里,我们将讨论这两种过渡类型。
一旦执行具有给定许可证的任何指令,就会立即发生硬过渡4。CPU停止运行,经过一些停机周期后进入新模式。
与硬过渡不同,软过渡不会立即发生在任何指令执行时。相反,指令最初以降低的吞吐量执行(最慢为正常速度的1/4),而不改变频率。如果CPU决定每单位时间内正在执行足够多的重型指令,并且达到了特定的阈值,则会发生向更高编号的许可证的过渡。
也就是说,CPU明白,如果只有少量的重型指令到达,或者即使有很多指令到达但在考虑其他非重型指令时它们并不密集,那么减少频率可能是不值得的。
根据上述情况,我们可以制定一些合理的指导方针。您永远不必担心128位指令,因为它们从不引起与许可证相关的3降频。
此外,你也不必担心256位宽指令会导致降频。如果你没有使用大量的向量化浮点数运算,那么你很可能也不会使用重型指令,所以这对你来说是适用的。实际上,编译器在你使用适当的-march选项时已经广泛地插入了256位指令,特别是用于数据移动和自动向量化循环。1虽然我们将会看到,这有点不准确,因为AVX-512指令可以将速度设置为此许可证,而一些AVX/2指令则不能。
2128位宽意味着使用xmm寄存器,无论它们是在哪个指令集中引入的 - 主流的AVX-512包含了大多数/全部新指令的128位变体。
3请注意“与许可证相关”的词句 - 您当然可能遭受其他导致降频的原因,例如热量、功率或电流限制,而128位指令可能会触发这种情况,但我认为在桌面或服务器系统上是相当不太可能的(低功耗、小尺寸设备另当别论)。
4显然,我们只谈论从一个更高级别许可证转换到另一个更高级别许可证的情况,例如当执行硬过渡L1指令时从L0转换到L1。如果您已经处于L1或L2状态,则不会发生任何转换 - 如果您已经处于相同级别,并且您不基于任何特定指令而转换到较低编号的级别,而是在一定时间内运行而没有任何较高编号级别的指令。
5个中,AVX2 turbo更常见,这一点我从来没有真正理解,因为与AVX相比,256位指令与AVX2同样相关,并且大多数实际触发AVX turbo(L1许可证)的重型指令实际上是AVX中的FP指令,而不是AVX2。唯一的例外是AVX2整数乘法。重要的不是指令助记符,而是512位向量宽度
您可以使用AVX-512VL指令的256位版本,例如vpternlogd ymm0,ymm1,ymm2
,而不会导致AVX-512 turbo惩罚。
相关:动态确定恶意AVX-512指令执行位置是关于glibc初始化代码或其他东西中一个AVX-512指令留下了脏的上部ZMM导致剩余进程生命周期内最大turbo受限的情况。(或者直到vzeroupper
)
虽然256位FP数学指令的轻/重使用还可能产生其他turbo影响,其中一些是由于热量原因。但通常在现代CPU上使用256位是值得的。
无论如何,这就是为什么gcc -march=skylake-avx512
默认使用-mprefer-vector-width=256
。对于任何给定的工作负载,值得尝试-mprefer-vector-width=512
,也许是128,这取决于工作负载中有多少可以自动向量化。
告诉GCC调整您的CPU(例如-march=native
),它将会做出明智的选择。虽然在桌面Skylake-X上,turbo惩罚比Xeon要小。如果您的代码确实从512位向量化中获益,则支付这个惩罚是值得的。
popcnt
或add
之类的标量指令可以使用端口 1。 因此,vpand
和vpaddb
等吞吐量从每个时钟周期的 3 个降至 2 个。如果您使用带有两个 512 位 FMA 单元的 SKX,则额外的一个单元将在端口 5 上启动,因此 FMA 将与洗牌竞争。)-march=skylake-avx512 -mprefer-vector-width=128
编译时,我实际上看到了你刚才提到的-- vmovdqu64(%rdx),%xmm0
,vmovdqu64 0x10(%rsi),%xmm6
等等。 看起来GCC 8.2做得不对(或者不是你期望的)? - HCSFxmm
运行 AVX2 指令不会像使用 ymm
操作数指令一样产生任何惩罚? - xiver77
-mpreferred-vector-width=256
选项。我不知道它是否会阻止gcc在直接内部使用之外_永远_生成AVX-512指令,但这是可能的。然而,我不知道有任何区分“重”和“轻”指令的选项。通常这不是一个问题,因为如果你关闭AVX-512并且没有一堆FP操作,你可能正在针对L0,而AVX-512 light仍然是L1。 - BeeOnRope