内在函数和寄存器(SSE)

Posted

技术标签:

【中文标题】内在函数和寄存器(SSE)【英文标题】:Intrinsics and registers(SSE) 【发布时间】:2017-07-31 11:30:31 【问题描述】:

我对 SSE 有疑问。

据我所知,SSE 由 XMM 寄存器组成。并且(据我所知)如果我需要将一些值从 SSE 的某个部分移动到其他部分 - 我必须使用汇编语言。例如movdqa xmm7, xmm6。但它不起作用。

我需要将值移动到另一个单元格 我该怎么办?

【问题讨论】:

这是一个洗牌,如果您使用的是内在函数,则不需要 asm。见_mm_shuffle_epi32 @Jester 非常感谢。它有效。 注意@Jester的评论不仅限于shuffle操作;你真的不需要 asm 来使用任何 SSE。 <xmmintrin.h> 标头还定义了对应于 XMM 寄存器可以保存的类型(__m128__m128i__m128d),以及对它们进行操作的内在函数,对应于 SSE 指令。 请注意,洗牌整数值和洗牌浮点值有单独的洗牌指令。在某些处理器上,在整数和浮点运算之间进行切换会产生少量时间损失。 【参考方案1】:

当您使用 C++ 编写代码时,您使用内部函数,并且由编译器分配寄存器,与通常的非向量代码相同。

相关:

Understanding how the instrinsic functions for SSE use memory SIMD Intrinsics and Persistent Variables/State Pointer to result of AVX load (_mm256_load_si256)

您在调试器监视窗口中看到的值是单个 xmm 值的表示,它可能位于寄存器或内存中。如果是寄存器,不是两个不同的xmm寄存器,所以movdqa xmm7, xmm6是无关紧要的。

您在名为tt 的变量中看到的事实表明它在内存中,Visual Studio 调试器大多数时候无法显示在寄存器中实现的变量。 (这可能是由于调试版本,而在发布时它会在一个寄存器中)。

_m128i 类型被定义为数组的联合,因为它可能被不同的操作视为由具有不同元素大小的向量组成。您正在查看 32 位值的向量。要重新排列组件,请使用 32 位随机播放 _mm_shuffle_epi32,正如 the comment 中所指出的那样。

相同的 shuffle 可用于交换 64 位值。对于其他值大小(小于 32),有 8 位随机播放 _mm_shuffle_epi8。不过它需要SSSE3。如果您想将 SSE2 作为基线,可以在多个内在函数中实现目标:有 _mm_extract_epi16/_mm_insert_epi16,也可以通过使用一系列 _mm_unpack 操作和/或移位来实现一些 shuffle。

【讨论】:

以上是关于内在函数和寄存器(SSE)的主要内容,如果未能解决你的问题,请参考以下文章

SSE 内在函数检查零标志

用于灰度到 ARGB 转换的 C++ SSE2 或 AVX2 内在函数

强制 AVX 内部函数改为使用 SSE 指令

如何将单精度浮点数的 XMM 寄存器转换为整数?

C++ 中 SSE/AVX 的 x86 CPU 调度

如何“删除” SSE 寄存器末尾的字节?