高效(在 Ryzen 上)将 __m256 的奇数元素提取到 __m128 中的方法?

问题描述 投票:0回答:1

是否有一种固有的或另一种有效的方法将 AVX 寄存器的 64 位组件的高/低 32 位组件重新打包到 SSE 寄存器中?使用 AVX2 的解决方案是可以的。

到目前为止,我正在使用以下代码,但分析器说它在 Ryzen 1800X 上运行缓慢:

// Global constant
const __m256i gHigh32Permute = _mm256_set_epi32(0, 0, 0, 0, 7, 5, 3, 1);

// ...

// function code
__m256i x = /* computed here */;
const __m128i high32 = _mm256_castsi256_si128(_mm256_permutevar8x32_epi32(x),
  gHigh32Permute); // This seems to take 3 cycles
c++ vectorization x86-64 sse avx2
1个回答
5
投票

在 Intel 和 Zen 2 或更高版本上, 使用

_mm256_permutevar8x32_ps
洗牌+投射对于 1 个向量是最佳的。一条 1-uop 指令是您将获得的最好的指令。 (AMD Zen 2 和 Zen 3 上 2 微指令。Zen 4 上 1 微指令。https://uops.info/

使用

vpermps
而不是
vpermd
来避免任何 int / FP 旁路延迟的风险,如果您的输入向量是由
pd
指令而不是负载或其他东西创建的。使用 FP 洗牌的结果作为整数指令的输入在 Intel 上通常没问题,但我不太确定是否将 FP 指令的结果提供给整数洗牌。)

尽管如果针对 Intel 进行调整,您可能会尝试更改周围的代码,以便您可以洗牌到每个 128b 通道的底部 64 位,以避免使用通道交叉洗牌。 (然后你可以只使用

vshufps ymm
,或者如果针对 KNL 进行调整,
vpermilps
因为 2-input
vshufps
速度较慢。)

对于 AVX512,有

_mm256_cvtepi64_epi32
(
vpmovqd
)
跨通道打包元素,并进行截断。


在 Zen 1 上,过马路的洗牌速度很慢Agner Fog 没有

vpermd
的数字,但他列出了
vpermps
(可能在内部使用相同的硬件)3 微指令,5c 延迟,每 4c 吞吐量一个。 https://uops.info/ 确认 Zen 1 的这些数字。

Zen 2 和 Zen 3 大部分都有 256 位宽的向量执行单元,但有时它们的通道交叉洗牌元素小于 128 位需要多个微指令。 Zen 4 有所改进,例如 0.5c 的吞吐量

vpermps
和 4c 的延迟。

vextractf128 xmm, ymm, 1
在 Zen 1 上非常高效(1c 延迟,0.33c 吞吐量),这并不奇怪,因为它已经将 256b 寄存器作为两个 128b 的一半进行跟踪。
shufps
也很高效(1c 延迟,0.5c 吞吐量),并且可以让您将两个 128b 寄存器洗牌成您想要的结果。

这也为您不再需要的 2 个

vpermps
洗牌面具节省了 2 个寄存器。所以我建议:

__m256d x = /* computed here */;

// Tuned for Zen 1 through Zen 3.  Probably sub-optimal everywhere else.
__m128 hi = _mm_castpd_ps(_mm256_extractf128_pd(x, 1));  // vextractf128
__m128 lo = _mm_castpd_ps(_mm256_castpd256_pd128(x));    // no instructions
__m128 odd  = _mm_shuffle_ps(lo, hi, _MM_SHUFFLE(3,1,3,1));
__m128 even = _mm_shuffle_ps(lo, hi, _MM_SHUFFLE(2,0,2,0));

在 Intel 上,使用 3 次洗牌而不是 2 次可以得到最佳吞吐量的 2/3,第一个结果有 1c 的额外延迟。

在 Zen 2 和 Zen 3 中,

vpermps
是 2 uops,
vextractf128
是 1,提取物 + 2x
vshufps
优于 2x
vpermps
.

Alder Lake 上的 E-cores 也有 2 uop

vpermps
但 1 uop
vextractf128
vshufps xmm

© www.soinside.com 2019 - 2024. All rights reserved.