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

Posted

技术标签:

【中文标题】如何将单精度浮点数的 XMM 寄存器转换为整数?【英文标题】:How can I convert an XMM register of single-precision floats to integers? 【发布时间】:2013-09-17 23:23:29 【问题描述】:

我在 XMM 寄存器中有一堆打包的浮点数(使用 SSE 内在函数):

__m128 xmm = _mm_set_ps(4.0f, 3.0f, 2.0f, 1.0f);

我想一次性将所有这些转换为整数。我找到了一个内在函数,它可以满足我的需求 (_mm_cvtps_pi16()),但它会产生 4x16 位 short 而不是完整的 int。一个名为 _mm_cvtps_pi32() 的内在函数产生 int,但仅适用于 xmm 中的两个较低值。我可以使用它,提取值,移动东西并再次使用它,但是有没有更简单的方法?为什么没有简单的 32 位压缩浮点 -> 32 位整数指令?确定两者都适合 XMM 寄存器的相同空间吗?

编辑:好的,我现在看到 _mm_cvtps_pi32() 返回 __m64 而不是 __m128,这意味着它在 MMX 样式的 MM... 寄存器上运行。这可以解释为什么它只返回两个整数,但现在我想知道:

为 x64 编译时会遇到问题吗?据报道,那里不支持 __m64... 为什么在 SSE 推出时他们没有扩展这条指令?

谢谢!

【问题讨论】:

【参考方案1】:

根据this 文档:__m128d _mm_cvtps_epi32(__m128d a) 生成一个cvtps2dq 指令,它可以满足您的需求。

【讨论】:

值得花点时间了解后缀。在这种情况下,问题的pi32 直接导致此答案的epi32 - 扩展的e。扩展、并行、32 位整数。 我以前认为__m128d 是用来存储两个64 位浮点数的,所以我没有更仔细地看这个内在函数。知道为什么会有这种返回类型吗? 好吧,看起来我们都错了,返回类型实际上是__m128i,现在一切正常。内在函数记录在 MSDN 上 SSE2 文档的 __m128d 部分中,不过,出于我不明白的原因。 我不能保证文档(不是我写的,我只是搜索了我想要的指令),但似乎另一个答案也建议_mm_cvtps_epi32,所以它可能值得一试。 非常感谢。只是我发现这些文档非常混乱。现在接受。【参考方案2】:

使用文档(_mm_cvtps_epi32):

Magic documentation.

【讨论】:

我想坚持使用 MSDN 文档对我不利。我认为这是要走的路,因为我在 Windows 上用 Visual C++ 编写。 有时需要深入搜索:MSDN documentation Intel Intrinsics Guide 是更有用的参考 - 它是 Linux/Windows/OS X 的文档工具,比 MSDN 更全面/更准确、更快速/更易于使用。

以上是关于如何将单精度浮点数的 XMM 寄存器转换为整数?的主要内容,如果未能解决你的问题,请参考以下文章

将浮点数从高 xmm 四字移动到低 xmm 四字

将单个浮点数移动到 xmm 寄存器

有没有办法用 xor 翻转 32 位浮点数的符号位?

怎么将4字节16进制转化成浮点数

FORTRAN里怎样把数值类型(整数,浮点数)转换为字符串

如何将单精度浮点数转换为十进制?