AVX/SSE 回合向下浮动并返回整数向量
AVX/SSE round floats down and return vector of ints?
有没有办法使用 AVX/SSE 获取浮点数向量,向下舍入并生成整数向量?所有的地板内在方法似乎都会产生浮点的最终向量,这很奇怪,因为舍入会产生一个整数!
SSE 通过您选择的截断(朝零(或当前舍入模式(通常是 IEEE 默认模式,最接近的平局四舍五入到偶数(从 FP 转换为整数。 像nearbyint()
,不像round()
的抢七是远离0。 如果你在 x86 上需要这种舍入模式,你必须模拟它,也许使用截断作为构建块。
CVTPS2DQ并CVTTPS2DQ相关指令,以将打包的单精度 float
s 转换为有符号双字整数。 助记符中带有额外 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在硬件中提供的其他两种舍入模式,地板(朝向-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) );
使用转换说明:
int _mm_cvt_ss2si (__m128 a)
将 a
的低 32 位浮点分量转换为整数并返回该整数。a
的前三个组成部分将被忽略。
__m128i _mm_cvtps_epi32 (__m128 a);
将所有四个 32 位浮点数转换为整数,并返回 4 个 32 位整数的向量。
这些是经常使用的。还有其他变体来处理转换。
单指令选项:
- 截断为零:
__m128i _mm_cvttps_epi32(__m128 a)
- 从四舍五入到最近:
__m128i _mm_cvtps_epi32(__m128 a)
两个指令,使用 SSE4.1 ROUNDPS
然后cvtps_epi32
- 向
-INF
四舍五入:__m128 _mm_floor_ps(__m128 s1)
- 向
+INF
四舍五入:__m128 _mm_ceil_ps(__m128 s1)
如果要将数据保留为 FP 格式,请仅使用其他截断或最接近的roundps
形式。
对于正数,截断和下限相同。 对于负整数,cvtt(-4.9) = -4
,但floor(-4.9) = -5.0
。 查看floorf()
与 truncf()
.
如果 FP 值超出INT_MIN
到INT_MAX
范围,cvttps
和 cvtps
将为您提供0x80000000
(即 INT_MIN
,只是符号位集(,英特尔称之为"整数无限"值。 它还将引发 FP 无效异常,但默认情况下会屏蔽 FP 异常。
- 让bool方法返回其他整数
- C 字符串返回字符串的整数/双精度/长整型值
- 如何使此递归函数从给定的起始位置返回最小的整数?
- 如何优化代码以返回最接近给定整数的数字,但给定列表中不存在?
- 查找存储在二叉搜索树的所有非叶子中的数据总和?(返回整数的独立递归函数
- C++:为什么我的掷骰子函数在掷骰子数量时只返回偶数整数?
- 从 C++ 中定义的异常返回整数
- 递归返回可被给定整数 k 整除的位数
- 类型转换问题:返回为整数而不是浮点/类型
- 分段故障在类之间返回整数
- 如何将字符串传递给函数并返回整数
- atof 仅返回整数
- AVX/SSE 回合向下浮动并返回整数向量
- 元函数计算 x^n 并返回整数限制而不溢出(如果不可能)
- 我已经声明了整数并尝试返回整数,但它给了我错误
- C++ 堆栈字符串流函数返回整数与 ASCII
- 是否可以从模板函数返回整数
- 为什么 floor 不返回整数?
- 如何同时在本机 dll 中返回整数和字符 * 变量C++?
- 为什么difftime只返回整数