Comportamiento de Environment.ProcessorCount en Windows

En Windows, la propiedad Environment.ProcessorCount ahora respeta la afinidad de proceso y el límite máximo del objeto de trabajo en el uso de la CPU.

Descripción del cambio

En versiones anteriores de .NET, la propiedad Environment.ProcessorCount en Windows devuelve el número de procesadores lógicos en la máquina. La propiedad omite la afinidad de proceso y el límite máximo del objeto de trabajo en el uso de la CPU. Ese comportamiento de Windows es incoherente con el comportamiento en sistemas operativos basados en Unix, donde se respetan esos límites.

A partir de .NET 6, el comportamiento de Environment.ProcessorCount en Windows es coherente con el comportamiento en el sistema operativo basado en Unix. En general, Environment.ProcessorCount devuelve el mínimo de:

  • Procesadores lógicos de la máquina.
  • Procesadores con los que tiene afinidad el proceso, si este se ejecuta con afinidad de CPU.
  • El límite de uso de CPU redondeado al siguiente número entero, si el proceso se ejecuta con un límite de uso de CPU.

En la tabla siguiente se muestra cómo cambia el valor de Environment.ProcessorCount de .NET 5 a .NET 6 en una máquina con ocho procesadores lógicos:

Entorno .NET 5 .NET 6
Proceso con afinidad con dos procesadores lógicos (Windows) 8 2
Proceso con afinidad con dos procesadores lógicos (Unix) 2 2
Uso de CPU limitado al equivalente de dos procesadores lógicos (Windows) 8 2
Uso de CPU limitado al equivalente de dos procesadores lógicos (Unix) 2 2

Versión introducida

6.0

Motivo del cambio

Esta propiedad suele usarse para determinar el factor de paralelismo de un proceso. Hemos observado que el hecho de no limitar el valor de la propiedad en función de la afinidad y el límite de uso de CPU puede provocar un peor rendimiento.

Revise el código que usa Environment.ProcessorCount para reducir verticalmente el factor de paralelismo en función de la configuración de la aplicación o del sistema. Incluso si el código tiene en cuenta la máscara de afinidad del proceso o el límite de uso de CPU del objeto de trabajo, puede acabar usando un paralelismo inferior al previsto.

Revise el código que espera Environment.ProcessorCount para devolver el número total de procesadores lógicos de la máquina, por ejemplo, para mostrarlo a un usuario. En su lugar, puede usar una llamada PInvoke a las API Win32 GetSystemInfo o GetNativeSystemInfo.

Si el código funciona peor como resultado de este cambio, puede usar la variable de entorno DOTNET_PROCESSOR_COUNT para reemplazar el número de procesadores que el tiempo de ejecución de .NET cree que están disponibles y que la propiedad Environment.ProcessorCount notifica. Por ejemplo, si establece DOTNET_PROCESSOR_COUNT en 4, Environment.ProcessorCount pasará por alto cualquier afinidad de proceso y límite de uso de CPU y devolverá 4. Para imitar el comportamiento de .NET 5, establezca la variable de entorno en %NUMBER_OF_PROCESSORS%.

API afectadas