在英特尔intrinsics webapp中,有几项行动似乎从桑迪桥变为哈斯威尔 . 例如,许多插入操作(如_mm256_insertf128_si256)显示如下的成本表:
Performance
Architecture Latency Throughput
Haswell 3 -
Ivy Bridge 1 -
Sandy Bridge 1 -
我发现这种差异令人费解 . 这有什么不同,因为有新的指令可以取代这些或补偿它的东西(哪些)?有谁知道Skylake是否进一步改变了这个模型?
1 回答
TL:DR :根据Agner Fog's testing,所有车道交叉shuffle /插入/提取在Haswell / Skylake上有3c延迟,但在SnB / IvB上有2c延迟 .
这可能是执行单元中的1c某种不可避免的旁路延迟,因为SnB through Broadwell have standardized latencies of 1, 3, or 5 cycles, never 2 or 4 cycles中的实际执行单元 . (SKL制作一些uops uc 4c,包括FMA / ADDPS / MULPS) .
(请注意,对于使用128b ALU执行AVX1的AMD CPU(例如Bulldozer / Piledriver / Steamroller),insert128 / extract128比VPERM2F128这样的shuffle要快得多 . )
内在指南有时会出现虚假数据 . 我认为这是指示reg-reg形式的指令,除了负载内在函数的情况 . 即使它是正确的,内在指南也没有给出非常详细的性能图;请参阅下文,了解Agner Fog的表格/指南 .
(我内心的一个问题是,很难使用
PMOVZX
/PMOVSX
作为负载,因为提供的唯一内在函数需要__m128i
源,即使pmovzxbd
仅加载4B或8B(ymm) . 它和/或广播加载(带有AVX1 / 2的_mm_set1_*
)是压缩内存中常量的好方法 . 应该有内在函数需要const char*
(因为它允许别名)) .在这种情况下,Agner Fog's measurements显示SnB / IvB对于reg-reg
vinsertf128
/vextractf128
具有2c延迟,而他对Haswell的测量(3c延迟,每1c输出一次)与英特尔_2876218的另一种情况一致,即英特尔内在指南中的数字是错误 . It's great for finding the right intrinsic, but not a good source for reliable performance numbers. 它没有告诉你有关执行端口或总uop的任何信息,甚至经常忽略吞吐量数字 . Latency is often not the limiting factor in vector integer code anyway. 这可能是为什么英特尔允许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 . IDK为什么吞吐量如此不同 . 也许Agner的测试略有不同?有趣的是,
vextractf128 mem,reg, i
不是一个2-fused-domain-uop指令,只使用存储数据和存储地址端口,而不是shuffle单元 . (Agner Fog 's table lists it as using one p015 uop on SnB, 0 on IvB. But even on SnB, doesn'在任何特定列都有一个标记,所以IDK哪个是正确的 . )讽刺的是
vextractf128
在一个立即操作数上浪费了一个字节 . 我猜他们不知道他们将使用EVEX进行下一个向量长度扩展,并且正准备立即从0..3开始 . 但是对于AVX1 / 2,你永远不应该使用immediate = 0来使用该指令 . 相反,只需movups mem, xmm
或movaps xmm,xmm
. (我认为编译器知道这一点,并且当你使用index = 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吞吐量一次的添加,是mul / fma的一半 . )所以 using many vector accumulators is essential in most FP algorithms 用于保持8或10个FMA一次飞行以使吞吐量饱和,如果存在循环携带的依赖性 . 否则,如果循环体足够小,则无序执行将立即在飞行中进行多次迭代 .
整数通道内运行通常只有1c延迟,因此您需要更少的并行度来最大化吞吐量(并且不受延迟限制) .
用于将数据输入/输出ymm的高半部分的其他选项都不是更好
vperm2f128
或AVX2vpermps
更贵 . 通过内存将导致存储转发失败 - >插入的大延迟(2个窄存储 - >宽负载),所以它在有用的情况下尽量避免vinsertf128
.如总是,尽量使用最便宜的指令序列 . 例如对于水平总和或其他减少,总是首先减少到128b向量,因为跨车道改组是缓慢的 . 通常它只是
vextractf128
/addps xmm
,然后通常horizontal 128b .正如Mysticial所提到的,Haswell和后来的128b向量的SnB / IvB的通道内载矢量混洗吞吐量的一半 . SnB / IvB可以
pshufb
/pshufd
,每0.5c吞吐量一个,但每1c只有一个shufps
(甚至128b版本);对于在AVX1中具有ymm版本的其他shuffle也是如此(例如vpermilps
,它显然仅存在,因此可以在一条指令中完成FP加载和混洗) . Haswell got rid of the 128b shuffle unit on port1 altogether, instead of widening it for AVX2.re:skylake
Agner Fog的指南/ insn表于12月更新,包括Skylake . 有关更多链接,另请参阅x86标记wiki . reg,reg形式具有与Haswell / Broadwell相同的性能 .