¿Qué es la afinidad de la CPU?

Affinity es el mapeo entre hilos de software y hardware: puede tener 8 hilos y 8 núcleos, pero el mapeo entre ellos es variable.

El problema es que el sistema operativo puede migrar hilos. Por lo tanto, si no establece afinidad, pueden suceder dos cosas malas:

  1. un hilo puede moverse a un núcleo diferente, perdiendo así el contenido de su caché
  2. dos hilos pueden terminar en el mismo núcleo, dejando otro núcleo sin usar.

La afinidad se expresa como una “máscara” que describe dónde se puede ejecutar un subproceso. Por ejemplo, puede vincular un subproceso (de software) a un subproceso de hardware, un núcleo (lo que significa que puede elegir o migrar entre subprocesos de hardware), un socket (que le da todos los núcleos de ese chip procesador) o ninguno. De puede especificar un conjunto de estos, como todos los núcleos impares …

Si establecer afinidad y cómo establecerlo, generalmente es una función de su aplicación. Si tiene 4 hilos y 8 núcleos en 2 zócalos:

  • puede asignarles [0-x-1-x] [2-x-3-x] con los corchetes que indican los sockets. Esta es una buena solución si su aplicación usa mucho ancho de banda y poca reutilización de caché.
  • puede asignarles [0–1–2–3] [xxxx]. Esta es una mejor solución si la aplicación está vinculada al cómputo y los núcleos necesitan compartir muchos datos de caché. (¡Esto reduce al menos 20ns de su latencia de coherencia!) No es bueno para las aplicaciones vinculadas al ancho de banda, ya que los cuatro hilos ahora están luchando por el ancho de banda de un solo socket.

Si tiene hilos de hardware, el problema de afinidad se vuelve aún más interesante: con 8 hilos en 4 núcleos y dos hilos de hardware por núcleo:

  • puede asignarlos [0–1] [2–3] [4–5] [6–7], o
  • puede asignarlos [0–4] [1–5] [2–6] [3–7]

La primera opción tiene más sentido, la mayoría de las veces, pero también podrías probar la otra. Puede que tenga sentido para su aplicación.

Si está tratando de entender la afinidad, realmente necesita la herramienta “hwloc”. Localidad de hardware portátil (hwloc) Puede generar imágenes detalladas de cómo está organizado su procesador. Ejemplo:

Esta es una configuración de dos sockets con L3 compartido por socket y L2 / L1 compartido entre los hilos de hardware en un solo núcleo. Si quieres minimizar el tráfico de coherencia, ¡es mejor que lo sepas! (Además, si es más probable que algunos de sus subprocesos hablen con el PCI, los quiere en el zócalo uno, no en el cero). (Nota personal: he estado imprimiendo el equivalente al anterior en tamaño de póster para el Desembarco del Caballero. Con 4 dominios numa, 68 núcleos en 34 mosaicos y 272 hilos de hardware, tener una imagen general es la única forma de obtener la imagen general. Por así decirlo).

Es solo una configuración proporcionada por su sistema operativo que determina en qué núcleos un subproceso es elegible para ejecutarse. La mayoría de las veces, lo mejor es no establecer afinidad, ya que permite que el subproceso se ejecute lo antes posible, en lugar de esperar hasta que un núcleo (o conjunto) en particular esté disponible. La razón por la que importa es que los núcleos particulares pueden compartir caché con otros núcleos, bancos de memoria o incluso dispositivos IO. La afinidad se puede utilizar para garantizar que un proceso esté siempre en el “mejor” núcleo para un dispositivo de red, por ejemplo, o que dos subprocesos intensivos en caché permanezcan en núcleos que no comparten recursos de caché. A menudo, la afinidad se establece simplemente para “reservar” un núcleo para un hilo o proceso, si hay hilos “más hambrientos” que también se ejecutan.

En sistemas multinúcleo o multiprocesador, el sistema operativo programa un subproceso activo en un núcleo de CPU disponible. Cuando los subprocesos pueden ingresar a los estados de espera, bloqueo, inactividad, suspensión, etc., donde actualmente no requieren ningún recurso de CPU. La próxima vez que el subproceso se active, el núcleo original asignado podría estar ocupado y el siguiente núcleo disponible atenderá el subproceso. Este cambio de contexto agrega retrasos diminutos. En general, esto tiene poco impacto en la gran mayoría de las aplicaciones.

Sin embargo, hay algunas aplicaciones en las que esto puede afectar el rendimiento. Piense en un servicio de larga duración que requiere baja latencia y gran cantidad de trabajo. Otro caso es cuando su CPU tiene grupos de núcleos o su sistema tiene grupos de núcleos (sistemas multisocket). Aquí es donde entra en juego la afinidad del procesador. Los subprocesos se pueden asignar explícitamente para utilizar un determinado conjunto de núcleos. Puede asegurarse de que los subprocesos permanecen en lugar de ser atendidos por el siguiente núcleo disponible.

La afinidad del procesador o la fijación de la CPU permite la vinculación y la desvinculación de un proceso o un subproceso a una unidad central de procesamiento (CPU) o un rango de CPU, de modo que el proceso o el subproceso se ejecutará solo en la CPU o CPU designadas en lugar de cualquier CPU . Esto se puede ver como una modificación del algoritmo de programación de cola central nativa en un sistema operativo de multiprocesamiento simétrico. Cada elemento en la cola tiene una etiqueta que indica su procesador de parentesco. En el momento de la asignación de recursos, cada tarea se asigna a su procesador de parentesco con preferencia a los demás.

La afinidad de la CPU permite vincular un proceso o procesos múltiples a un núcleo de CPU específico de manera que los procesos se ejecuten solo desde ese núcleo específico. Al intentar realizar pruebas de rendimiento en un host con muchos núcleos, es aconsejable ejecutar varias instancias de un proceso, cada una en un núcleo diferente. Esto permite una mayor utilización de la CPU.

Puede denegar el acceso a un proceso a algunas CPU en particular (o núcleos, etc.). En este caso, el proceso no estará en la lista preparada para esas CPU y podría ejecutarse más lentamente si usa bien el procesamiento paralelo. Pero el sistema utilizará mejor los otros núcleos y funcionará bien (dejando de lado los problemas de almacenamiento en caché)