Die CompareGreaterThan-Methoden von SSE und SSE2 behandeln NaN-Eingaben ordnungsgemäß

Die folgenden Methoden System.Runtime.Intrinsics.X86.Sse und System.Runtime.Intrinsics.X86.Sse2 wurden so korrigiert, dass sie NaN-Eingaben ordnungsgemäß verarbeiten und dem Hardwareverhalten der äquivalenten Methoden in der System.Runtime.Intrinsics.X86.Avx-Klasse entsprechen:

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

Änderungsbeschreibung

Zuvor gaben NaN-Eingaben an die aufgelisteten Methoden Sse und Sse2 ein falsches Ergebnis zurück. Das Ergebnis wich außerdem von dem Ergebnis ab, das von der entsprechenden Methode in der Avx-Klasse generiert wurde.

Ab .NET 5 behandeln diese Methoden NaN-Eingaben korrekt und geben dieselben Ergebnisse wie die entsprechenden Methoden in der Avx-Klasse zurück.

Die Branchenstandardarchitekturen SSE (Streaming SIMD Extensions) und SSE2 (Streaming SIMD Extensions 2) bieten keine direkte Hardwareunterstützung für diese Vergleichsmethoden, sodass Sie in Software implementiert sind. Zuvor waren die Methoden nicht ordnungsgemäß implementiert und haben NaN-Eingaben fehlerhaft behandelt. Bei Code, der aus systemeigener Architektur portiert wird, kann das fehlerhafte Verhalten zu Fehlern führen. Bei einem 256-Bit-Codepfad können die Methoden außerdem abweichende Ergebnisse von den entsprechenden Methoden in der Avx-Klasse erzeugen.

Als Beispiel dafür, wie die Methoden zuvor fehlerhaft waren, können Sie CompareNotGreaterThan(x,y) als CompareLessThanOrEqual(x,y) für reguläre ganze Zahlen implementieren. Für NaN-Eingaben berechnet diese Logik jedoch das falsche Ergebnis. Stattdessen werden bei Verwendung von CompareNotLessThan(y,x) die Zahlen korrekt verglichen undNaN-Eingaben werden berücksichtigt.

Eingeführt in Version

5.0

  • Wenn das vorherige Verhalten ein Fehler war, ist keine Änderung erforderlich.

  • Wenn das vorherige Verhalten gewünscht war, können Sie dieses Verhalten beibehalten, indem Sie den relevanten Aufruf wie folgt ändern:

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

Betroffene APIs