为什么英特尔将一些 Haswell AVX 延迟时间宣传为 Sandy Bridge 的 3 倍慢?

12

在英特尔的内置函数网页应用程序中,一些操作似乎从Sandy Bridge到Haswell有所恶化。例如,许多插入操作(如_mm256_insertf128_si256)显示以下成本表:

   Performance
 Architecture   Latency   Throughput
 Haswell        3         -
 Ivy Bridge     1         - 
 Sandy Bridge   1         - 

我觉得这个差异很令人困惑。这个差异是因为有新的指令替代了旧的指令,还是有其他补偿措施(哪些)?有人知道Skylake是否进一步改变了这个模型吗?


5
在Sandy Bridge中,向量置换执行单元的功率不如以前那么强大。其他一些指令(pmulld, roundss/sd/ps/pd)也受到了影响。这只是构建处理器时通常的成本效益分析的一部分。"不太重要"的指令可能会在未来的设计中被牺牲。尽管如此,向量置换仍然非常重要,但至少他们将吞吐量保持在每个时钟周期1次的水平。 - Mysticial
6
Haswell的重点在于功耗。尽管特性缩小,但它确实做得非常、非常好。你不能两者兼得。 - Hans Passant
1个回答

13
简述: 在Haswell/Skylake上,所有的跨越/插入/提取操作都需要3个时钟周期的延迟,但在SnB/IvB上只需要2个时钟周期,根据Agner Fog的测试

这可能是执行单元中的1个时钟周期加上某种不可避免的旁路延迟,因为从SnB到Broadwell的实际执行单元具有标准化的1、3或5个时钟周期延迟,从未出现过2或4个时钟周期。(SKL使一些uops uops 4c,包括FMA/ADDPS/MULPS)。

(请注意,在使用128b ALU进行AVX1的AMD CPU上(例如Bulldozer/Piledriver/Steamroller),insert128/extract128比VPERM2F128等洗牌操作快得多。)


内置函数指南有时存在虚假数据。我认为它应该是针对reg-reg形式的指令,除了load内置函数的情况。即使数据正确,内置函数指南也不能提供非常详细的性能信息;请参阅下面有关Agner Fog表/指南的讨论。

对于Intrinsics(指处理器指令的一种编程方式)之一的Pet Peeve是,由于提供的所有Intrinsics都采用__m128i源,因此难以将PMOVZX / PMOVSX用作加载操作,即使pmovzxbd只加载4B或8B (ymm)。它和/或广播加载(_mm_set1_* with AVX1/2)是压缩内存中常量的好方法。应该提供Intrinsics采用const char*(因为它可以与任何类型别名)。


在这种情况下,Agner Fog的测量表明,SnB/IvB对于reg-reg vinsertf128/vextractf128具有2c延迟,而他对Haswell的测量(3c延迟,每个1c tput一个)与Intel的表格相符。因此,这是另一种情况,即Intel的内在指南中的数字是错误的。它很适合查找正确的内在指令,但不是可靠性能数据的好源。 它不告诉您任何执行端口或总uops,并且通常甚至省略了吞吐量数字。 在向量整数代码中,延迟通常不是限制因素。 这可能是为什么Intel让Haswell的延迟增加的原因。
reg-mem形式有显著的不同。vinsertf128 y,y,m,i 具有如下lat/recip-tput:IvB: 4/1,Haswell/BDW: 4/2,SKL: 5/0.5。它始终是2个uop指令(融合域),使用一个ALU uop。我不知道为什么吞吐量如此不同。也许Agner的测试方式略有不同?
有趣的是,vextractf128 mem,reg, i 不使用任何ALU uops。这是一个2个融合域uop指令,只使用存储数据和存储地址端口,不使用洗牌单元。(Agner Fog的表格列出它在SnB上使用一个p015 uop,在IvB上使用0个。但即使在SnB上,也没有在任何特定列中标记,所以我不知道哪个是正确的。)
令人愚蠢的是vextractf128浪费了一个字节的立即操作数。我猜他们不知道他们将使用EVEX进行下一个向量长度扩展,并准备让立即数从0..3。但对于AVX1/2,您永远不应该使用立即=0的指令。相反,只需使用movups mem, xmmmovaps xmm,xmm。(我认为编译器知道这一点,并且在您使用具有索引= 0的内部函数时执行此操作,就像他们为_mm_extract_epi32等执行的操作一样(movd)。)
延迟在FP代码中更为常见,Skylake对于FP ALU来说非常强大。他们设法将FMA的延迟降低到4个周期,因此mulps/addps/fma...ps的延迟都是4c,吞吐量为0.5c。 (Broadwell的mulps/addps = 3c延迟,fma = 5c延迟。Haswell的addps=3c延迟,mul/fma=5c)。 Skylake取消了单独的加法单元,因此addps的延迟实际上从3c恶化到4c,但吞吐量增加了一倍。(Haswell/BDW仅使用每1c吞吐量的一个addps,这只有mul/fma的一半)。因此,在大多数FP算法中,使用许多向量累加器对于保持8或10个FMAs同时运行以饱和吞吐量至关重要,如果存在循环依赖,则必须如此。否则,如果循环体足够小,则乱序执行将同时有多个迭代在运行。
整数in-lane操作通常只有1c延迟,因此您需要更少的并行性来最大化吞吐量(并且不会受到延迟的限制)。

没有其他选项可以更好地将数据输入/输出ymm的高半部分

vperm2f128或AVX2 vpermps更加昂贵。通过内存会导致存储转发失败->插入大延迟(2个窄存储器->宽加载),因此显然很糟糕。在有用的情况下不要尝试避免vinsertf128

像往常一样,尽可能使用最便宜的指令序列。例如,对于水平求和或其他缩减,始终先缩减到128b向量,因为跨通道洗牌速度较慢。通常只需要vextractf128/addps xmm,然后是通常的水平128b

正如Mysticial所暗示的那样,Haswell及以后的处理器与SnB/IvB相比,在128位向量的内部通道向量洗牌吞吐量方面只有一半。 SnB/IvB可以每0.5个时钟周期进行一个pshufb / pshufd,但对于shufps(即使是128b版本),每1个时钟周期只能进行一个。对于其他在AVX1中具有ymm版本的洗牌操作(例如vpermilps),情况也是一样的,这些操作显然仅存在于FP加载和洗牌可以在一条指令中完成的情况下。 Haswell完全取消了端口1上的128b洗牌单元,而不是将其扩展为AVX2。

关于Skylake

Agner Fog的指南/指令表已于去年12月更新,包括Skylake。另请参阅标签wiki以获取更多链接。reg,reg形式的性能与Haswell / Broadwell相同。


我也很好奇他们为什么在port1上移除了shuffle单元,以及这与观察结果有何关系。我的有限知识表明,移除执行单元会影响吞吐量而非延迟。你是否提到它可能是导致延迟增加的原因之一? - orm
我已经接受了你的答案,并且很享受阅读它并查看你推荐的一些链接。我认为其他一些寻求更快速阅读的人可能会从开头的TLDR中受益。对于替代方案,我认为我的主要收获是大多数(全部?)将数据移动到/从ymm寄存器的高半部分的操作在延迟方面都很昂贵,尽管不一定在吞吐量方面。 - orm
@orm:删除port1随机单元对延迟没有影响,只对吞吐量有影响。(除非在资源冲突的情况下,指令不能在其输入准备就绪时立即启动,因为该端口正在运行需要p5的旧指令。)感谢您提出如何总结的建议;我完全不知道该写什么内容作为tl;dr。 - Peter Cordes

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