mask_new1 = _mm512_set_epi32(0, 3, 0, 3, 0, 3, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2);
s1 = _mm512_permutexvar_pd(mask_new1, r);
out1 = _mm512_mul_pd(s1, _mm512_mul_pd(b1, c1));
这里有什么方法/想法可以更快地执行置换操作吗?
搜索了其他置换操作,但几乎找不到线索可以为这个掩码做得更好。操作的延迟和吞吐量由内在函数指南指定为 3 和 1
1 单 uop shuffle 很好,并且对于端口 5 上的后端端口压力不是问题,除非您周围的代码有很多 shuffle。 (如果是这样,你就倒霉了,因为英特尔 CPU 只在端口 5 上运行 512 位随机播放)。
乱序执行可以隐藏延迟,无论如何你也不能做得更好。
即使
r
来自负载(而不是另一个计算),我认为仅使用车道内洗牌没有任何范围。例如从 128 位广播负载开始不起作用,因为您需要元素 2 和 3,而不仅仅是 0 和 1。
像
vshufpd ymm
这样的随机播放可以在 Ice Lake 和更新版本的 p1/p5 上运行,但这对 512 位随机播放没有帮助;当 512 位微指令运行时,端口 1 上的向量 ALU 被关闭。因此,任何随机播放最多只有 1c 的吞吐量(这很好,每次随机播放 2 次乘法,您不会在后端的随机播放端口上遇到瓶颈)。
你需要一个跨车道洗牌(因为你不能做一个 128 位广播然后
vshufpd
或 vpermilps/pd
)所以它必须是 3c 延迟,但是乱序执行可以隐藏延迟,除非它是长(循环携带)依赖链的关键路径。