AVX/SSE 轮向下浮动并返回整数向量?

2024-01-05

有没有办法使用 AVX/SSE 获取浮点数向量,向下舍入并生成整数向量?所有底层内在方法似乎都会产生一个最终的浮点向量,这很奇怪,因为四舍五入会产生一个整数!


SSE 可以根据您选择的截断(向零)或当前舍入模式(通常是 IEEE 默认模式,最接近的平局舍入到偶数)从​​ FP 转换为整数。nearbyint(),不像round()其中抢七局距离为 0。如果您需要 x86 上的舍入模式,你必须模仿它,也许用截断作为构建块 https://stackoverflow.com/questions/485525/round-for-float-in-c/24348037?noredirect=1#comment81665514_47329084.)

相关说明是CVTPS2DQ http://www.felixcloutier.com/x86/CVTPS2DQ.html and CVTTPS2DQ http://www.felixcloutier.com/x86/CVTTPS2DQ.html转换打包单精度floats to 有符号双字整数。助记符中带有额外 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/AVXROUNDPS http://www.felixcloutier.com/x86/ROUNDPS.html转换为整数之前的指令。

代码如下所示:

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) is:

__m128 dst = _mm_cvtps_epi32( _mm_floor_ps(__m128 src) );
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AVX/SSE 轮向下浮动并返回整数向量? 的相关文章

随机推荐