AVX 中缺少字节粒度屏蔽存储

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

我正在将代码从 SSE 迁移到 AVX。该代码使用

_mm_maskmoveu_si128
,它根据掩码有条件地存储 16 个字节。 32 字节的 AVX 等效项是
_mm256_maskmoveu_si256
,但该指令不存在。

如何有效地模拟它?

simd sse avx
1个回答
0
投票

MMX/SSE2 字节掩码存储 (

MASKMOVDQU
) 具有 NT 语义,并且在现代 CPU 上高效。例如Skylake 上具有 6 周期吞吐量的 10 微指令。或者在 Zen 4 上有 75 个 uop,具有 18 个周期延迟。除非掩码为全 1,否则您将拥有一个部分行 NT 存储,它会消耗现代多核 CPU。

如果你可以在不违反多线程正确性的情况下进行非原子加载/

vpblendvb
/存储,那应该可以很好地工作。(这需要AVX2来实现
_mm256_blendv_epi8
,不仅仅是AVX,还可能是你正在做的任何事情
__m256i
中的单个字节也需要 AVX2。)


唯一好的屏蔽存储(非 NT)是具有 dword 或 qword 粒度的 AVX

vmaskmovps
/
pd
(和 AVX2
vpmaskmovd/q
),或具有字节粒度 (vmovdqu8 mem{k}, ymm
) 的 
AVX-512BW。

AVX 屏蔽存储在 AMD 上非常慢,但 AVX-512 屏蔽存储在 Zen 4 上实际上非常高效(显然是单 uop)。我不知道为什么他们无法实现

vmaskmovps mem, ymm, ymm
的微码来与掩码进行比较并使用它,例如 2 uops 而不是 42。(https://uops.info/)。

AVX1 和 AVX-512 屏蔽存储在 Intel 上都很高效,就像 Skylake 上的 3 uops

vmaskmovps
(端口 0 + 端口 4(存储数据)+ 端口 2/3/7(存储地址)。端口 0 uop 可能是一个
vpmovd2m k, x/ymm
,用于获取双字元素的高位并在只能由微代码使用的内部
k
寄存器中制作
k
掩码。不幸的是,它无法微融合存储地址和存储地址数据微指令也可以在前端,像往常一样,除了存储之外还有微指令指令。

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