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
Empfohlene Maßnahme
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
System.Runtime.Intrinsics.X86.Sse.CompareGreaterThan(Vector128<Single>, Vector128<Single>)
System.Runtime.Intrinsics.X86.Sse.CompareGreaterThanOrEqual(Vector128<Single>, Vector128<Single>)
System.Runtime.Intrinsics.X86.Sse.CompareNotGreaterThan(Vector128<Single>, Vector128<Single>)
System.Runtime.Intrinsics.X86.Sse.CompareNotGreaterThanOrEqual(Vector128<Single>, Vector128<Single>)
System.Runtime.Intrinsics.X86.Sse.CompareScalarGreaterThan(Vector128<Single>, Vector128<Single>)
System.Runtime.Intrinsics.X86.Sse.CompareScalarNotGreaterThan(Vector128<Single>, Vector128<Single>)
System.Runtime.Intrinsics.X86.Sse2.CompareGreaterThan(Vector128<Double>, Vector128<Double>)
System.Runtime.Intrinsics.X86.Sse2.CompareGreaterThanOrEqual(Vector128<Double>, Vector128<Double>)
System.Runtime.Intrinsics.X86.Sse2.CompareNotGreaterThan(Vector128<Double>, Vector128<Double>)
System.Runtime.Intrinsics.X86.Sse2.CompareScalarGreaterThan(Vector128<Double>, Vector128<Double>)
System.Runtime.Intrinsics.X86.Sse2.CompareScalarNotGreaterThan(Vector128<Double>, Vector128<Double>)