Методы SSE и SSE2 CompareGreaterThan корректно обрабатывают входные данные, которые не являются числом
Следующие методы System.Runtime.Intrinsics.X86.Sse и System.Runtime.Intrinsics.X86.Sse2 были исправлены, чтобы корректно обрабатывать входные данные NaN
и соответствовать аппаратному поведению эквивалентных методов в классе System.Runtime.Intrinsics.X86.Avx:
CompareGreaterThan
CompareGreaterThanOrEqual
CompareNotGreaterThan
CompareNotGreaterThanOrEqual
CompareScalarGreaterThan
CompareScalarGreaterThanOrEqual
CompareScalarNotGreaterThan
CompareScalarNotGreaterThanOrEqual
Описание изменения
Ранее входные данные NaN
для методов Sse и Sse2 возвращали неверный результат. Результат также отличался от результата, создаваемого соответствующим методом в классе Avx.
Начиная с .NET 5 эти методы правильно обрабатывают входные данные NaN
и возвращают те же результаты, что и соответствующие методы в классе Avx.
Архитектура по стандартам отрасли потокового SIMD-расширения (SSE) и потокового SIMD-расширения 2 (SSE2) не обеспечивают прямую аппаратную поддержку этих методов сравнения, поэтому они реализуются в программном обеспечении. Ранее методы были неправильно реализованы и неправильно обрабатывали входные данные NaN
. В коде, перенесенном из машинного кода, неправильное поведение может привести к ошибкам. Для 256-разрядного пути к коду методы также могут давать результаты, отличные от результатов эквивалентных методов в классе Avx.
В качестве примера неправильной работы методов можно реализовать CompareNotGreaterThan(x,y)
как CompareLessThanOrEqual(x,y)
для обычных целых чисел. Однако для входных данных NaN
эта логика вычислит неверный результат. CompareNotLessThan(y,x)
правильно сравнивает числа и учитывает входные данные NaN
.
Представленные версии
5,0
Рекомендуемое действие
Если предыдущее поведение было ошибкой, изменение не требуется.
Если вы хотите сохранить предыдущее поведение, измените соответствующий вызов следующим образом:
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>)