Function core::arch::x86::_mm_setcsr
1.27.0 · source · pub unsafe fn _mm_setcsr(val: u32)
sse
and x86 only.Expand description
用 32 位无符号整数值设置 MXCSR 寄存器。
该寄存器控制 SIMD 指令如何处理浮点运算。修改该寄存器只会影响当前线程。
它包含几组标志:
-
异常标志 报告自上次重置后发生了哪些异常。
-
屏蔽标志 可用于屏蔽 (忽略) 的某些异常。默认情况下,这些标志都设置为 1,因此所有异常都被屏蔽。 屏蔽了异常后,处理器将简单地设置异常标志并继续操作。 如果未屏蔽该异常,则还会设置该标志,但是还会调用一个异常处理程序。
-
舍入模式标志 控制浮点指令的舍入模式。
-
非规范化为零模式
flags*
将所有将要归一化 (指数位全为零) 的数字转换为零。
异常标志
-
_MM_EXCEPT_INVALID
: 执行了无效的操作 (例如,将无穷大除以无穷大)。 -
_MM_EXCEPT_DENORM
: 试图对非规范化数字进行操作的操作。这主要会导致精度降低。 -
_MM_EXCEPT_DIV_ZERO
: 发生被零除。 -
_MM_EXCEPT_OVERFLOW
: 发生数值溢出异常,即结果太大无法表示 (例如,绝对值大于2^128
的f32
)。 -
_MM_EXCEPT_UNDERFLOW
: 发生数字下溢异常,即结果太小而无法以规范化的方式表示 (例如,f32
绝对值小于2 ^-126
。) -
_MM_EXCEPT_INEXACT
: 发生不精确结果异常 (又名 精度异常)。这意味着由于舍入而损失了一些精度。 例如,分数1/3
无法在 32 位或 64 位浮点数并对其进行计算将导致引发此异常。精度异常非常常见,因此通常会被屏蔽。
可以使用便捷函数 _MM_GET_EXCEPTION_STATE
和 _MM_SET_EXCEPTION_STATE
读取和设置异常标志。
例如,要检查某个操作是否引起一些溢出:
_MM_SET_EXCEPTION_STATE(0); // 清除所有异常标志
// 执行计算
if _MM_GET_EXCEPTION_STATE() & _MM_EXCEPT_OVERFLOW != 0 {
// 处理上溢
}
Run掩蔽标志
每个异常标志都有一个屏蔽标志: _MM_MASK_INVALID
、_MM_MASK_DENORM
、_MM_MASK_DIV_ZERO
、_MM_MASK_OVERFLOW
、_MM_MASK_UNDERFLOW
、_MM_MASK_INEXACT
。
可以通过设置单个屏蔽位
但是,由于默认情况下所有掩码位都设置为 1,因此更常见的是要 禁用 某些位。例如,要掩盖下溢异常,请使用:
警告:未屏蔽的异常将导致调用异常处理程序。
标准处理程序将简单地终止该进程。
因此,在这种情况下,任何下溢异常都将使用诸如 signal: 8, SIGFPE: erroneous arithmetic operation
之类的内容终止当前进程。
舍入模式
使用两位描述舍入模式。可以使用便捷包装 _MM_GET_ROUNDING_MODE()
和 _MM_SET_ROUNDING_MODE(mode)
进行读取和设置。
舍入模式为:
-
_MM_ROUND_NEAREST
: (default) 四舍五入到最接近无限精度值。如果两个值相等接近,则四舍五入为偶数 (即,最低有效位将为零)。 -
_MM_ROUND_DOWN
: 向负无穷大舍入。 -
_MM_ROUND_UP
: 向正无穷大舍入。 -
_MM_ROUND_TOWARD_ZERO
: 向零 (truncate) 舍入。
Example:
Denormals-are-zero/Flush-to-zero 模式
如果设置了此位,则将要反规范化的值将设置为零。默认情况下是关闭的。
您可以通过辅助函数 _MM_GET_FLUSH_ZERO_MODE()
和 _MM_SET_FLUSH_ZERO_MODE()
读取和 enable/disable 此模式: