在某些内在函数中,他们使用后缀x
,如_mm256_set1_epi64x
。它的含义是什么?作为参考,_mm256_set1_epi32
没有此后缀。
答案 0 :(得分:4)
TL:DR: MMX-> SSE2转换内在函数采用非x _mm_set/set1_epi64
名称。
这是基于当前函数名称,已知历史记录和一些编译器行为的猜测:
第一个英特尔SIMD内在函数用于MMX。 __m64
是与SSE2 __m128i
和AVX2 __m256i
相当的MMX。当时没有64位x86 CPU,因此最宽set
内在函数为__m64 _mm_set_pi32 (int e1, int e0)
。根据内在发现者的说法,movq mm0, rax
仍然没有任何内在因素。我认为你可以/应该将int64_t
投射到__m64
。 (虽然上次我在去年左右进行了实验,gcc或clang(我忘记了)在优化MMX asm方面表现不佳。老化编译器支持是避免MMX用于新项目的另一个原因。)
当SSE2被引入in 2001时,AMD64 / x86-64仍未发布,并且几年内英特尔不会支持它。 (当时他们希望IA-64 / Itanium成为未来并取代x86)。我没有检查过旧的手册,但我想是的
__m128i _mm_set1_epi64 (__m64 a)
当时可用,并且
__m128i _mm_set1_epi64x (__int64 a)
可能不是。 (请注意,__int64
不是来自int64_t
的{{1}}。但它是64位整数类型,无需担心。)
<stdint.h>
代表扩展(?)Packed Integer。 epi
代替epi
告诉您它是SSE内在的,而不是MMX内在的。对于从一个元素宽度转换为另一个元素宽度的内部函数,如果明确地识别操作(至少对于我所看到的那些),内在函数使用源宽度。例如pi
(_mm_packs_epi32
)或packssdw
(_mm_unpackhi_epi16
)。 PMOVZX需要两个数字,因为有punpckhwd
(_mm_cvtepu8_epi32
),pmovzxbd
(_mm_cvtepu8_epi64
等等。
编译器当然支持32位模式下的64位整数,因此英特尔包含用于处理它们的内在函数是有意义的。但是IIRC,在某些编译器中pmovzxbq
内在函数仅在编译64位代码时可用。 64x
仅与转换为标量64位整数/从标量64位整数相关,因此您无法找到64x
版x
或类似内容。
根据编译器的不同,_mm_add_epi64
可能仍然存在这个仅64位的内容,但历史记录解释了为什么_mm256_set1_epi64x
而不是64x
。
(抱歉,我很懒,并没有在Godbolt上组合实验来检查当前编译器32x
。看看你从铸造-m32
获得什么样的asm可能会很有趣到int64_t
并在32位代码中使用__m64
内在函数。)