简述: 在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, xmm
或
movaps 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。另请参阅x86标签wiki以获取更多链接。reg,reg形式的性能与Haswell / Broadwell相同。
pmulld
,roundss/sd/ps/pd
)也受到了影响。这只是构建处理器时通常的成本效益分析的一部分。"不太重要"的指令可能会在未来的设计中被牺牲。尽管如此,向量置换仍然非常重要,但至少他们将吞吐量保持在每个时钟周期1次的水平。 - Mysticial