Поделиться через


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

Изменение описания

Ранее NaN входные данные перечисленных Sse и методы Sse2 возвращали неверный результат. Результат также отличается от результата, созданного соответствующим методом в классе Avx.

Начиная с .NET 5 эти методы правильно обрабатывают входные данные NaN и возвращают те же результаты, что и соответствующие методы в классе Avx.

Расширения SIMD потоковой передачи (SSE) и расширения SIMD потоковой передачи 2 (SSE2) архитектуры наборов инструкций (ISAs) не обеспечивают прямую поддержку оборудования для этих методов сравнения, поэтому они реализованы в программном обеспечении. Ранее методы были неправильно реализованы, и они неверно обрабатывали входные данные 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