SSE 可以从 FP 转换为整数,您可以选择截断(接近零)或当前舍入模式(通常是 IEEE 默认模式,最接近 tiebreaks 舍入为偶数。像 nearbyint(),不像 round() 中的 tiebreak远离 0。如果您需要 x86 上的舍入模式,you have to emulate it, perhaps with truncate as a building block。)
相关指令是CVTPS2DQ 和CVTTPS2DQ 将压缩单精度floats 转换为有符号双字整数。助记符中带有额外 T 的版本执行截断而不是当前的舍入模式。
; xmm0 is assumed to be packed float input vector
cvttps2dq xmm0, xmm0
; xmm0 now contains the (rounded) packed integer vector
或者使用内在函数,__m128i _mm_cvt[t]ps_epi32(__m128 a)
对于 x86 在硬件中提供的其他两种舍入模式,floor(朝向 -Inf)和 ceil(朝向 +Inf),一种简单的方法是在转换为整数之前使用此 SSE4.1/AVX ROUNDPS 指令。
代码如下所示:
roundps xmm0, xmm0, 1 ; nearest=0, floor=1, ceil=2, trunc=3
cvtps2dq xmm0, xmm0 ; or cvttps2dq, doesn't matter
; xmm0 now contains the floored packed integer vector
对于 AVX ymm 向量,在指令前加上“V”,并将 xmm 更改为 ymm。
ROUNDPS 是这样工作的
对 xmm2/m128 中的单精度浮点值进行四舍五入,并将结果放入 xmm1。取整方式由 imm8 决定。
舍入模式(立即数/第三个操作数)可以有以下值(取自当前英特尔文档的表4-15 - Rounding Modes and Encoding of Rounding Control (RC) Field):
Rounding Mode RC Field Setting Description
----------------------------------------------------------
Round to nearest (even) 00B Rounded result is the closest to the infinitely precise result. If two values are equally close, the result is nearest (even) the even value (i.e., the integer value with the least-significant bit of zero).
Round down (toward −∞) 01B Rounded result is closest to but no greater than the infinitely precise result.
Round up (toward +∞) 10B Rounded result is closest to but no less than the infinitely precise result.
Round toward 0 (truncate) 11B Rounded result is closest to but no greater in absolute value than the infinitely precise result.
舍入运算的返回向量是float 而不是int 的可能原因可能是,通过这种方式,进一步的运算总是可以是浮点运算(在舍入值上)并且转换为int 会如图所示。
在引用的文档中可以找到相应的内在函数。将上述代码转换为内在函数(依赖于Rounding Control (RC) Field)的示例是:
__m128 dst = _mm_cvtps_epi32( _mm_floor_ps(__m128 src) );