Методы 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