Udostępnij za pośrednictwem


Metody SSE i SSE2 CompareGreaterThan prawidłowo obsługują dane wejściowe NaN

Następujące metody System.Runtime.Intrinsics.X86.Sse i System.Runtime.Intrinsics.X86.Sse2 zostały naprawione, aby prawidłowo obsługiwać dane wejściowe NaN i dopasować zachowanie sprzętowe równoważnych metod w klasie System.Runtime.Intrinsics.X86.Avx:

  • CompareGreaterThan
  • CompareGreaterThanOrEqual
  • CompareNotGreaterThan
  • CompareNotGreaterThanOrEqual
  • CompareScalarGreaterThan
  • CompareScalarGreaterThanOrEqual
  • CompareScalarNotGreaterThan
  • CompareScalarNotGreaterThanOrEqual

Zmień opis

Wcześniej dane wejściowe NaN do wymienionych metod Sse i Sse2 zwracały niepoprawny wynik. Wynik różnił się również od wyniku wygenerowanego przez odpowiednią metodę w klasie Avx.

Począwszy od platformy .NET 5, te metody prawidłowo obsługują NaN danych wejściowych i zwracają te same wyniki co odpowiednie metody w klasie Avx.

Rozszerzenia SIMD (SSE) przesyłania strumieniowego oraz rozszerzenia SIMD 2 (SSE2) w architekturze zestawu instrukcji (ISA) nie oferują bezpośredniego wsparcia sprzętowego dla tych metod porównania, dlatego są one implementowane w oprogramowaniu. Wcześniej metody zostały nieprawidłowo zaimplementowane i nieprawidłowo obsłużyły NaN danych wejściowych. W przypadku kodu przeniesionego z natywnego nieprawidłowe zachowanie może powodować błędy. W przypadku 256-bitowej ścieżki kodu metody mogą również generować różne wyniki niż równoważne metody w klasie Avx.

Jako przykładowy sposób, w jaki metody były wcześniej nieprawidłowe, można zaimplementować CompareNotGreaterThan(x,y) jako CompareLessThanOrEqual(x,y) dla zwykłych liczb całkowitych. Jednak w przypadku NaN danych wejściowych logika oblicza niewłaściwy wynik. Zamiast tego użycie CompareNotLessThan(y,x) prawidłowo porównuje liczby i oraz uwzględnia NaN wejścia.

Wprowadzona wersja

5.0

  • Jeśli poprzednie zachowanie było usterką, nie jest wymagana żadna zmiana.

  • Jeśli poprzednie zachowanie było pożądane, można zachować to zachowanie, zmieniając odpowiednie wywołanie w następujący sposób:

    • 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)

Interfejsy API, których dotyczy problem