X86 在通道中,在AVX2中跨64位元素数据移动

X86 在通道中,在AVX2中跨64位元素数据移动,x86,intel,simd,micro-optimization,avx2,X86,Intel,Simd,Micro Optimization,Avx2,在ymmregs中,是否有任何寄存器到寄存器1 AVX或AVX2指令可以在128位通道的64位半部之间以任何方式移动数据,而不使用当代Intel2上的端口5 1对于内存源,存在这样一种东西,形式为D和Q广播指令 2 Haswell通过Skylake-S(尽管如果在SKX中实现的AVX-512中存在任何内容,则值得一提) 我认为在1 reg reg指令中不可能,但存储/重新加载可以在没有端口5的通道中移动数据。即使是像dppd或vcvtps2pd这样的时髦玩意儿也需要端口5洗牌。所有寄存器源洗牌

ymm
regs中,是否有任何寄存器到寄存器1 AVX或AVX2指令可以在128位通道的64位半部之间以任何方式移动数据,而不使用当代Intel2上的端口5


1对于内存源,存在这样一种东西,形式为
D
Q
广播指令


2 Haswell通过Skylake-S(尽管如果在SKX中实现的AVX-512中存在任何内容,则值得一提)

我认为在1 reg reg指令中不可能,但存储/重新加载可以在没有端口5的通道中移动数据。即使是像
dppd
vcvtps2pd
这样的时髦玩意儿也需要端口5洗牌。所有寄存器源洗牌指令都在Haswell和更高版本的端口5上运行(直到Ice Lake在另一个端口上添加第二个可以执行洗牌的洗牌单元)

显然,未对齐的重新加载可以执行任何字节移位,但这将导致存储转发暂停,并且您必须屏蔽不需要的数据

完全在加载端口上运行,与
vbroadcastsd
完全相同,它是低qword的车道内广播
vmovsldup
并且只需要一个加载端口,但不能满足在64位通道的一半之间移动的要求

没有任何
movhdup
复制每条车道内的高半部,只有
movddup
复制低双精度FP元素。SSE3用于xmm,AVX1用于ymm版本


正如@harold指出的,我们可以将数据从高64位放入低64位。但它在YMM版本中不可用。它可能是唯一一条具有特殊用途执行单元的指令,可以在随机洗牌之外执行
psadbw
在64位元素中工作<代码>vdbpsadbw是SKX上p5的1 uop<代码>mpsadbw是多uop,包括2p5<代码>phadd说明也包含在2p5中



Zen 2对
vpshufd ymm
()的吞吐量为0.5c。在处理粒度小于128位的车道交叉洗牌时,它比Intel慢,但在车道内洗牌和128位洗牌(如
vperm2f128

等)上性能良好。我假设您排除了Ice Lake(第二个可以运行一些洗牌的洗牌单元)或pre Haswell,其中整数洗牌的吞吐量为2/时钟。对于1/c洗牌吞吐量,存储+广播重新加载至少值得考虑。@PeterCordes-是的,我打算将其限制为当前可用的支持AVX2的CPU,基本上是Haswell通过Skylake和变体。用脚注澄清。实际上我想的是AVX-512之前的版本,但如果ICL AVX-512之前的版本中有答案的话,我也很感兴趣。
PHMINPOSUW
是否算数?是的,Zen1对于uops车道交叉洗牌的次数非常随意。我曾希望Zen2在将shuffle ALU扩展到256位时会更像Intel,但也许他们实际上没有这样做。所以它有点像Merom,它只有一个64位的洗牌单元,使pshufd变慢,但pshuflw变快。(可能Zen2的洗牌端口每个都有2个车道内洗牌单元。因此车道内洗牌是全速的,但是车道交叉需要额外的UOP,以便粒度<128位)。广播仍然很快(4c延迟),而且
vperm2f128
很好(3c延迟)。@harold-我打算不允许它,因为我正在使用AVX指令查找
ymm
。我没有提到
ymm
部分,所以我猜从技术上讲它是这样做的,但是它没有
ymm
版本,只是在AVX中,因为默认的VEX编码几乎什么都有。我刚刚编辑了?n以使
ymm
显式。