x86 在 AVX512 之前没有对 FPunsigned 的本机支持,vcvtps2udq
(https://www.felixcloutier.com/x86/vcvtps2udq https://www.felixcloutier.com/x86/vcvtps2udq)。对于标量,通常只需转换为 64 位有符号 (cvtss2si rax, xmm0
)并取其中的低 32 位(在 EAX 中),但这对于 SIMD 来说不是一个选项。
没有 AVX-512,理想情况下,您可以使用签名转换 (cvtps2dq
)并得到相同的结果。 IE。如果你的浮点数非负并且 INT_MAX (2147483647.0
).
See 如何使用SSE/AVX高效执行double/int64转换? https://stackoverflow.com/questions/41144668/how-to-efficiently-perform-double-int64-conversions-with-sse-avx用于相关的 double->uint64_t 转换。如果需要的话,全范围的应该可以从 double->uint64_t 到 float->uint32_t 进行调整。
Another possibility (for 32-bit float->uint32_t) is just range-shifting to signed in FP, then flipping back in integer. INT32_MIN ^ convert(x + INT32_MIN)
. But that introduces FP rounding for small integers because INT32_MIN is outside the -224 .. 224 range where a float
can represent every integer. e.g. 5
would be rounded to the nearest multiple of 28 during conversion. So that's not usable; you'd need to try straight conversion and range-shifted conversion, and only use the range-shifted conversion if straight conversion gave you 0x80000000
. (Perhaps using the straight conversion result as a blend control for SSE4 blendvps
?)
对于 float->int32_t 的打包转换,有 SSE2cvtps2dq xmm, xmm/m128
docs https://www.felixcloutier.com/x86/cvtps2dq. (cvttps2dq
转换为截断为 0,而不是当前默认的舍入模式(最接近的舍入模式,如果您没有更改它)。
Any negative float less than -0.5 will convert to integer -1 or lower; as an uint32_t
that bit-pattern represents a huge number. Floats outside the -231..231-1 range get converted to 0x80000000
, Intel's "integer indefinite" value.
如果您没有找到,只有 cvtps2pi 签名转换为 MMX 寄存器,您需要更好的地方来搜索:
-
https://stackoverflow.com/tags/sse/info https://stackoverflow.com/tags/sse/info - links
-
https://www.felixcloutier.com/x86/ https://www.felixcloutier.com/x86/x86 指令集列表。
-
https://www.officedaytime.com/simd512e/simd.html https://www.officedaytime.com/simd512e/simd.html- 按类别/功能列出的指令列表
-
https://software.intel.com/sites/landingpage/IntrinsicsGuide/ https://software.intel.com/sites/landingpage/IntrinsicsGuide/- 列出了仅公开单个指令功能的内在函数的 asm 指令助记符。通常,使用内在函数编写 C 比手动编写 C 更好,特别是如果您还不了解相对常见/简单的指令,例如
cvtps2dq
and cvttps2dq
.
-
https://agner.org/optimize/ https://agner.org/optimize/- 他的 asm 优化指南有一章是关于 SIMD 的,其中有一个方便的表格,其中包含不同类型的数据移动指令。
-
如何将单精度浮点数的 XMM 寄存器转换为整数? https://stackoverflow.com/questions/18861499/how-can-i-convert-an-xmm-register-of-single-precision-floats-to-integers- 指向正确方向的指针,但仅涵盖有符号转换。我没有找到完全相同的副本。