Share via


Os métodos SSE e SSE2 CompareGreaterThan manipula adequadamente com entradas NaN

Os seguintes métodos System.Runtime.Intrinsics.X86.Sse e System.Runtime.Intrinsics.X86.Sse2 foram corrigidos para manipular adequadamente as entradas NaN e corresponder ao comportamento de hardware dos métodos equivalentes no System.Runtime.Intrinsics.X86.Avx:

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

Descrição das alterações

Anteriormente, as entradas NaN para os métodos Sse e Sse2 retornavam um resultado incorreto. O resultado também diferia do resultado gerado pelo método correspondente na classe Avx.

A partir do .NET 5, esses métodos manipulam corretamente com as entradas NaN e retornam os mesmos resultados que os métodos correspondentes na classe Avx.

As (ISAs) arquiteturas padrão do setor SSE (Extensões SIMD de Streaming) e SSE2 (Extensões SIMD de Streaming 2) não dão suporte direto de hardware a esses métodos de comparação, portanto, eles são implementados em software. Anteriormente, os métodos eram implementados de modo inadequado e manipulavam as entradas NaN incorretamente. Para código portado do nativo, o comportamento incorreto poderá introduzir bugs. Para um caminho de código de 256 bits, os métodos também podem produzir resultados diferentes dos métodos equivalentes na classe Avx.

Como exemplo de como os métodos estavam incorretos anteriormente, você poderá implementar CompareNotGreaterThan(x,y) como CompareLessThanOrEqual(x,y) para inteiros regulares. No entanto, para as entradas NaN, essa lógica calculará o resultado errado. Em vez disso, usar CompareNotLessThan(y,x) comparará os números corretamente e considerará as entradas NaN.

Versão introduzida

5,0

  • Se o comportamento anterior foi um bug, nenhuma alteração será necessária.

  • Se o comportamento anterior foi o desejado, você poderá manter esse comportamento alterando a chamada relevante da seguinte maneira:

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