Udostępnij za pośrednictwem


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

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

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

Opis zmiany

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

Począwszy od platformy .NET 5, te metody poprawnie obsługują NaN dane wejściowe i zwracają te same wyniki co odpowiednie metody w Avx klasie.

Rozszerzenia SIMD przesyłania strumieniowego (SSE) i streaming SIMD Extensions 2 (SSE2) branżowych architektur (ISA) nie zapewniają bezpośredniej obsługi sprzętu dla tych metod porównania, więc są one implementowane w oprogramowaniu. Wcześniej metody zostały nieprawidłowo zaimplementowane i nieprawidłowo obsłużyły NaN dane wejściowe. 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 do równoważnych metod w Avx klasie.

Jako przykładowy sposób, w jaki metody były wcześniej niepoprawne, można zaimplementować CompareNotGreaterThan(x,y) jako CompareLessThanOrEqual(x,y) zwykłe liczby całkowite. Jednak w przypadku NaN danych wejściowych logika oblicza nieprawidłowy wynik. Zamiast tego użycie porównuje CompareNotLessThan(y,x) liczby poprawnie i bierze NaN pod uwagę dane wejściowe.

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)

Dotyczy interfejsów API