SSE 和 SSE2 CompareGreaterThan 方法正确处理 NaN 输入
以下 System.Runtime.Intrinsics.X86.Sse 和 System.Runtime.Intrinsics.X86.Sse2 方法已修复为正确处理 NaN
输入,并匹配 System.Runtime.Intrinsics.X86.Avx 类中等效方法的硬件行为:
CompareGreaterThan
CompareGreaterThanOrEqual
CompareNotGreaterThan
CompareNotGreaterThanOrEqual
CompareScalarGreaterThan
CompareScalarGreaterThanOrEqual
CompareScalarNotGreaterThan
CompareScalarNotGreaterThanOrEqual
更改描述
以前,向列出的 Sse 和 Sse2 方法提供 NaN
输入所返回的结果不正确。 此结果也不同于 Avx 类中相应方法生成的结果。
从 .NET 5 开始,这些方法会正确地处理 NaN
输入,并返回与 Avx 类中相应方法相同的结果。
流式处理 SIMD 扩展 (SSE) 和流式处理 SIMD 扩展 2 (SSE2) 行业标准体系结构 (ISA) 没有为这些比较方法提供直接的硬件支持,因此它们是在软件中实现的。 以前,这些方法没有得到正确的实现,也没有正确地处理 NaN
输入。 对于从本机移植的代码,不正确的行为可能会引入 bug。 对于 256 位代码路径,这些方法可能还会生成与 Avx 类中等效方法不同的结果。
有关说明这些方法以前是如何不正确的示例,可以为常规整数将 CompareNotGreaterThan(x,y)
实现为 CompareLessThanOrEqual(x,y)
。 不过,对于 NaN
输入,相应逻辑计算出的结果不正确。 相反,使用 CompareNotLessThan(y,x)
可以正确地比较数字,并 考虑 NaN
输入。
引入的版本
5.0
建议操作
如果以前的行为是 bug,则不需要进行任何更改。
如果需要以前的行为,则可以通过更改相关调用来维护此行为,如下所示:
CompareGreaterThan(x,y)
->CompareNotLessThanOrEqual(x,y)
CompareGreaterThanOrEqual(x,y)
->CompareNotLessThan(x,y)
CompareNotGreaterThan(x,y)
->CompareLessThanOrEqual(x,y)
CompareNotGreaterThanOrEqual(x,y)
->CompareLessThan(x,y)
CompareScalarGreaterThan(x,y)
->CompareScalarNotLessThanOrEqual(x,y)
CompareScalarGreaterThanOrEqual(x,y)
->CompareScalarNotLessThan(x,y)
CompareScalarNotGreaterThan(x,y)
->CompareScalarLessThanOrEqual(x,y)
CompareScalarNotGreaterThanOrEqual(x,y)
->CompareScalarLessThan(x,y)
受影响的 API
System.Runtime.Intrinsics.X86.Sse.CompareGreaterThan(Vector128<Single>, Vector128<Single>)
System.Runtime.Intrinsics.X86.Sse.CompareGreaterThanOrEqual(Vector128<Single>, Vector128<Single>)
System.Runtime.Intrinsics.X86.Sse.CompareNotGreaterThan(Vector128<Single>, Vector128<Single>)
System.Runtime.Intrinsics.X86.Sse.CompareNotGreaterThanOrEqual(Vector128<Single>, Vector128<Single>)
System.Runtime.Intrinsics.X86.Sse.CompareScalarGreaterThan(Vector128<Single>, Vector128<Single>)
System.Runtime.Intrinsics.X86.Sse.CompareScalarNotGreaterThan(Vector128<Single>, Vector128<Single>)
System.Runtime.Intrinsics.X86.Sse2.CompareGreaterThan(Vector128<Double>, Vector128<Double>)
System.Runtime.Intrinsics.X86.Sse2.CompareGreaterThanOrEqual(Vector128<Double>, Vector128<Double>)
System.Runtime.Intrinsics.X86.Sse2.CompareNotGreaterThan(Vector128<Double>, Vector128<Double>)
System.Runtime.Intrinsics.X86.Sse2.CompareScalarGreaterThan(Vector128<Double>, Vector128<Double>)
System.Runtime.Intrinsics.X86.Sse2.CompareScalarNotGreaterThan(Vector128<Double>, Vector128<Double>)