Compartir a través de


Los métodos SSE y SSE2 CompareGreaterThan controlan correctamente las entradas NaN

Los siguientes métodos System.Runtime.Intrinsics.X86.Sse y System.Runtime.Intrinsics.X86.Sse2 se han corregido para controlar correctamente las entradas de NaN y coincidir con el comportamiento de hardware de los métodos equivalentes de la clase System.Runtime.Intrinsics.X86.Avx:

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

Descripción del cambio

Anteriormente, las entradas de NaN a los métodos enumerados Sse y Sse2 devolvieron un resultado incorrecto. El resultado también difiere del resultado generado por el método correspondiente en la clase Avx.

A partir de .NET 5, estos métodos controlan correctamente las entradas NaN y devuelven los mismos resultados que los métodos correspondientes de la clase Avx.

Las arquitecturas del conjunto de instrucciones (ISA) SSE (Extensiones de SIMD de streaming) y SSE2 (Extensiones de SIMD de streaming 2) no proporcionan soporte de hardware directo para estos métodos de comparación, por lo que se implementan en el software. Anteriormente, los métodos se implementaron de manera incorrecta y manejaron incorrectamente las entradas NaN. En el caso del código migrado desde nativo, el comportamiento incorrecto puede introducir errores. En el caso de una ruta de acceso de código de 256 bits, los métodos también pueden producir resultados diferentes en los métodos equivalentes de la clase Avx.

Como ejemplo de cómo los métodos eran incorrectos anteriormente, puede implementar CompareNotGreaterThan(x,y) como CompareLessThanOrEqual(x,y) para enteros normales. Sin embargo, para la entrada NaN, esta lógica calcula el resultado incorrecto. En su lugar, al usar CompareNotLessThan(y,x), se comparan los números correctamente y se tienen en cuenta las entradas de NaN.

Versión introducida

5.0

  • Si el comportamiento anterior era un error, no se requiere ningún cambio.

  • Si se desea el comportamiento anterior, puede mantener ese comportamiento cambiando la invocación pertinente de la siguiente manera:

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

APIs afectadas