gpt4 book ai didi

avx - 仅使用 avx 而不是 avx2 转置 64 位元素

转载 作者:行者123 更新时间:2023-12-02 06:49:27 26 4
gpt4 key购买 nike

我想仅使用avx而不是avx2来实现64位转置操作。它应该这样做:

// in  = Hh Hl Lh Ll
// | X |
// out = Hh Lh Hl Ll

这就是使用 avx2 的样子:

#define SIMD_INLINE inline __attribute__ ((always_inline))

static SIMD_INLINE __m256i
x_mm256_transpose4x64_epi64(__m256i a)
{
return _mm256_permute4x64_epi64(a, _MM_SHUFFLE(3,1,2,0));
}

这是我能想到的最有效的解决方法,没有 avx2(使用 3 个 avx 指令):

static SIMD_INLINE __m256i
x_mm256_transpose4x64_epi64(__m256i a)
{
__m256d in, x1, x2;
// in = Hh Hl Lh Ll
in = _mm256_castsi256_pd(a);
// only lower 4 bit are used
// in = Hh Hl Lh Ll
// 0 1 0 1 = (0,0,1,1)
// x1 = Hl Hh Ll Lh
x1 = _mm256_permute_pd(in, _MM_SHUFFLE(0,0,1,1));
// all 8 bit are used
// x1 = Hl Hh Ll Lh
// 0 0 1 1
// x2 = Ll Lh Hl Hh
x2 = _mm256_permute2f128_pd(x1, x1, _MM_SHUFFLE(0,0,1,1));
// only lower 4 bit are used
// in = Hh Hl Lh Ll
// x2 = Ll Lh Hl Hh
// 0 1 1 0 = (0,0,1,2)
// ret: Hh Lh Hl Ll
return _mm256_castpd_si256(_mm256_blend_pd(in, x2, _MM_SHUFFLE(0,0,1,2)));
}

问题是大多数 avx swizzle 操作(例如解包)都在 128 位 channel 上运行,并且不会跨越 channel 边界。

任何人都可以制定更有效的实现方案吗?非常感谢!

最佳答案

我认为 3 条指令是你能做的最好的事情。 _mm256_blend_pd 非常便宜(如 vblendpsvpblendd),在 SnB/IvB 中的 2 个端口上运行,以及 Haswell 中的所有 3 个向量执行端口之后。 (即与向量 XOR 或 AND 一样便宜。)另外两个都需要随机播放端口,这是不可避免的。

当 vblendpd 将其数据从 FP 域转发到整数指令时,SnB 系列 CPU 上将出现 1 个周期的旁路延迟。尽管使用 AVX1,但没有任何 256b 整数指令可转发。

(来源:参见 Agner Fog 的 insn 表,链接自 标签 wiki。他的优化装配指南也有一些不错的洗牌表,但不关注 AVX/AVX2 的车道内挑战。)

<小时/>

这种模式几乎可以通过两条指令实现,但不完全是。

vshufpd (_mm256_shuffle_pd)为您提供 channel 内 2 源洗牌,但对数据移动有限制。与原始 SSE2 版本一样,每个目标元素只能来自固定的源元素。 8 位立即数有空间对四个源元素中的两个选择进行编码,但它们使硬件保持简单,并且仅对每个目标元素使用 1 位选择器。 256b 版本确实允许每个 128b channel 进行不同的洗牌,因此 imm8 的 4 位对于 vpshufd ymm 很重要。

无论如何,由于上车道需要从原始向量中获取其高位元素,而下车道需要从 perm128 向量中获取其高位元素,因此 src1、src2 排序的选择都无法满足我们的需要。

<小时/>

vshufpd 我认为编码比 vpermilpd imm8 短一个字节。 vpermilps/vpermilpd 直接形式的唯一用例似乎是加载和洗牌。 (vshufpd 仅当两个源操作数相同时才可用作完整的 channel 内洗牌)。 IDK 如果 vpermildp 可能会使用更少的能源或其他东西,因为它只有一个来源。

当然,编译器可以使用他们想要的任何指令来完成工作;他们可以使用内在函数优化代码,就像使用 + 运算符优化代码一样(它并不总是编译为 add 指令)。 Clang 实际上基本上忽略了使用内在函数进行指令选择的尝试,因为它以自己的内部格式表示洗牌,并对其进行优化。

关于avx - 仅使用 avx 而不是 avx2 转置 64 位元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37807595/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com