比如说,
_mm512_mask_mov_epi64
和 _mm512_mask_blend_epi64
之间有什么区别。除了参数的顺序和名称之外,我看不出有任何区别。英特尔内在函数指南中的伪代码看起来也完全等效:
混合:
FOR j := 0 to 7
i := j*64
IF k[j]
dst[i+63:i] := b[i+63:i]
ELSE
dst[i+63:i] := a[i+63:i]
FI
ENDFOR
dst[MAX:512] := 0
移动:
FOR j := 0 to 7
i := j*64
IF k[j]
dst[i+63:i] := a[i+63:i]
ELSE
dst[i+63:i] := src[i+63:i]
FI
ENDFOR
dst[MAX:512] := 0
有趣...我对内在函数不太熟悉。我们有一个
MOVAPD
,当掩码位为 0 时,它将目标设置为 0。该指令仅接受 2 个操作数。另一方面,BLEND 接受三个操作数,因此掩码用于在源 1 或源 2 之间进行选择。所以我的看法是第二个伪代码是错误的。您将拥有 a[...]
而不是 src[...]
,而您将拥有 0.而不是
src[...]
。
移动:
FOR j := 0 to 7
i := j*64
IF k[j]
dst[i+63:i] := src[i+63:i]
ELSE
dst[i+63:i] := 0
FI
ENDFOR
dst[MAX:512] := 0
这是英特尔文档版本:
(KL, VL) = (2, 128), (4, 256), (8, 512)
FOR j := 0 TO KL-1
i := j * 64
IF k1[j] OR *no writemask*
THEN DEST[i+63:i] := SRC[i+63:i]
ELSE
IF *merging-masking* ; merging-masking
THEN *DEST[i+63:i] remains unchanged*
ELSE DEST[i+63:i] := 0 ; zeroing-masking
FI
FI;
ENDFOR
DEST[MAXVL-1:VL] := 0