Límite de CPU

La afinidad de procesador , o afinidad de procesador , o afinidad de caché , es una  tecnología que garantiza que un proceso o subproceso se ancle y se desconecte de un núcleo de CPU, CPU o conjunto de procesadores específicos, de modo que el proceso o subproceso solo se ejecute en el núcleo especificado. , procesador o procesadores, y no en ningún procesador de un sistema multiprocesador. La afinidad del procesador se puede considerar como una modificación del algoritmo central de programación de la cola de tareas en un sistema operativo multiprocesador. Cada elemento de la cola de tareas tiene una etiqueta asociada , que especifica sus procesadores "relacionados".

Cuando se asignan recursos, cada tarea se distribuye preferiblemente para su ejecución en uno de los procesadores "relacionados". La afinidad del procesador aprovecha el hecho de que los datos y la configuración de un proceso que se ejecutaba anteriormente en un procesador determinado pueden estar disponibles más rápidamente para ese procesador que para otro. Esto puede suceder, por ejemplo, debido al almacenamiento en caché de datos de proceso en la memoria caché del procesador, así como en otras situaciones. La programación de un proceso de este tipo para que se ejecute en el mismo procesador mejora su rendimiento al reducir los eventos que degradan el rendimiento, como las pérdidas de caché.

Además, en algunos sistemas, cada uno de los procesadores puede tener un acceso más rápido a una región de RAM cercana. Al mismo tiempo, resulta racional mantener un vínculo constante del proceso con el procesador, cuyo acceso a la memoria RAM, donde se encuentran los datos de este proceso, es más rápido.

Un ejemplo práctico de afinidad de procesador es ejecutar varias instancias de una aplicación sin subprocesos, como algún software de representación de gráficos.

La implementación del algoritmo de programación de tareas, que brinda la posibilidad de vincularse al procesador, se implementa teniendo en cuenta las características de los procesadores específicos y la construcción de un sistema multiprocesador, que será controlado por dicho algoritmo. Algunas implementaciones, bajo ciertas circunstancias, permitirán que una tarea se transfiera a otro procesador, superando el enlace. Esto se hace en aquellos casos en los que, desde el punto de vista del programador, dicho cambio conducirá a un aumento en la eficiencia de la ejecución de la tarea. Por ejemplo, cuando dos tareas que hacen un uso intensivo del procesador (A y B) están vinculadas al mismo procesador y el otro procesador no está en uso, muchos programadores cambiarán la tarea B al segundo procesador para aprovechar al máximo el procesador disponible para el sistema. . La vinculación de la tarea B con el nuevo procesador en ese momento la establecerá el propio programador.

Funciones de implementación

La afinidad del procesador puede reducir efectivamente los problemas con los datos que ingresan al sistema y/o al caché del procesador. Pero no proporciona una solución a los problemas de equilibrio de carga [1] . La afinidad de CPU es más compleja en sistemas con una arquitectura heterogénea, lo que requiere una lógica de programación más sofisticada que en sistemas completamente homogéneos. Por ejemplo, un sistema con dos CPU de doble núcleo , cada una de las cuales admite la tecnología Hyper-Threading , presenta un problema para el algoritmo del programador, que asume la afinidad de la CPU. Si el sistema tiene una cantidad aún mayor de procesadores y, por ejemplo, no es completamente simétrico en sí mismo, entonces la complejidad del problema de la programación eficiente de tareas aumenta aún más.

Para el ejemplo anterior con dos procesadores de doble núcleo con hiperprocesos, el planificador debe implementar un sistema de enlace de dos niveles. En términos de eficiencia de caché, el trabajo dentro del mismo núcleo en diferentes subprocesos es equivalente, y el programador tiene derecho a mover libremente una tarea de un subproceso a otro. El nivel de "proximidad" de diferentes núcleos dentro de un procesador es menor, ya que comparten parcialmente un caché de procesador común, el nivel de "proximidad" de diferentes procesadores es aún menor. Debido a que también se comparten otros recursos, la afinidad de la CPU por sí sola no se puede utilizar como base para la programación de tareas. Por ejemplo, si un proceso se ejecutó recientemente en una CPU virtual con hiperprocesamiento en algún núcleo y esa CPU virtual está actualmente ocupada, pero una segunda CPU virtual del mismo núcleo está inactiva, la afinidad de la CPU basada en la eficiencia de la memoria caché implica que el proceso debe transferirse a un segundo procesador virtual (no en ejecución) del mismo núcleo. Sin embargo, las dos CPU virtuales compiten por casi todos los recursos informáticos, la memoria caché y los recursos de memoria. En esta situación, por regla general, sería más eficiente asignar el proceso a otro núcleo o CPU, si hay inactivos entre ellos. Esto puede resultar en un impacto único en el rendimiento debido al hecho de que el proceso reubicado tendrá que volver a llenar el caché con sus datos. Pero el rendimiento general puede ser mejor porque los dos procesos no tienen que competir por los recursos dentro de la misma CPU.

Para lograr la máxima eficiencia, el programador de tareas debe tener en cuenta todos estos aspectos. Los sistemas con niveles aún mayores de asimetría ( NUMA , clústeres, etc.) requieren una complejidad aún mayor del programador.

Implementación en sistemas operativos específicos

En Linux, la afinidad del procesador de un proceso se puede averiguar o configurar mediante la utilidad taskset [2] . Mediante programación, se pueden realizar las mismas acciones mediante las llamadas al sistema sched_getaffinity y sched_setaffinity [3] . La afinidad del subproceso se puede establecer o cambiar mediante una de las funciones de la biblioteca: pthread_setaffinity_np [4] o pthread_attr_setaffinity_np [5] .

En los sistemas SGI , un proceso podría asociarse con un conjunto de procesadores utilizando la utilidad dplace [6] .

En DragonFly BSD 1.9 (2007) y posteriores, la llamada al sistema usched_set [7] [8] se puede usar para controlar la afinidad de la CPU . En NetBSD 5.0, FreeBSD 7.2, DragonFly BSD 4.7 y posteriores, se pueden usar las llamadas al sistema pthread_setaffinity_np y pthread_getaffinity_np [9] . En NetBSD , la utilidad [10] psrset establece la afinidad de un subproceso con un conjunto específico de CPU. FreeBSD usa la utilidad cpuset [11] para crear conjuntos de procesadores y asignar procesos a esos conjuntos. En DragonFly BSD 3.1 (2012) y versiones posteriores, la utilidad usched se puede usar para asignar procesos a un conjunto específico de procesadores [12] .

En Windows NT y versiones posteriores, las afinidades de subprocesos y procesos se pueden configurar por separado mediante las llamadas API SetThreadAffinityMask [13] y SetProcessAffinityMask [14] o mediante la interfaz del Administrador de tareas (solo para procesos).

macOS proporciona una API de vinculación [15] que brinda sugerencias al kernel del sistema operativo sobre cómo programar subprocesos de acuerdo con los conjuntos de vinculación.

En Solaris , puede controlar la vinculación de procesos y procesos ligeros al procesador utilizando la utilidad pbind [16] . También se proporciona la llamada al sistema Processor_bind [17] . Las llamadas de interfaz de nivel superior también están disponibles, a saber, pset_bind [18] o lgrp_affinity_get [19] , utilizando los conceptos de conjunto de procesador y grupo de localidad, respectivamente.

En AIX , puede gestionar los enlaces de procesos mediante la utilidad bindprocessor [20] [21] y la llamada al sistema bindprocessor [20 ] [ 22 ] .

z/OS implementa quizás el programador de tareas más sofisticado que se usa en la actualidad. Proporciona una redistribución dinámicamente cambiante de recursos de hardware entre procesos, incluidos aquellos basados ​​en la vinculación de procesos a núcleos de procesadores individuales, procesadores y sus grupos [23]

Soporte en lenguajes de programación

La biblioteca estándar para el lenguaje de programación paralelo Julia incluye soporte experimental para la afinidad de proceso a procesador [24] .

Notas

  1. "Informe técnico - Afinidad del procesador" Archivado el 8 de junio de 2021 en Wayback Machine  - en tmurgent.com Archivado el 28 de abril de 2020 en Wayback Machine .
  2. taskset(1) -  Página man para desarrolladores de Linux - comandos personalizados  
  3. sched_setaffinity(2) -  Página man para desarrolladores de Linux - llamadas   al sistema
  4. pthread_setaffinity_np(3) -  Página de manual para desarrolladores de Linux - funciones de biblioteca  
  5. pthread_attr_setaffinity_np(3) -  Página de manual para desarrolladores de Linux - funciones de biblioteca  
  6. dplace.1 Archivado el 1 de julio de 2007.  — De sgi.com Archivado el 27 de marzo de 2009 en Wayback Machine . Consultado el 2007-07-06.
  7. usched_set(2)- configurando un proc's usched . Manual de llamadas al sistema DragonFly . DragonFlyBSD . Recuperado: 28 julio 2019.
  8. . Referencia cruzada BSD . DragonFlyBSD . Recuperado: 28 julio 2019.kern/kern_usched.c § sys_usched_set
  9. pthread_setaffinity_np(3)  - Manual de funciones de biblioteca de NetBSD , FreeBSD y DragonFly BSD
  10. psrset(8) -  Página del manual del administrador del sistema NetBSD  
  11. cpuset(1)  - Página del manual de comandos de usuario de FreeBSD  
  12. usched(8): ejecute un programa con un planificador de espacio de usuario específico y cpumask . Manual del administrador del sistema DragonFly . DragonFlyBSD . Recuperado: 28 julio 2019.
  13. SetThreadAffinityMask Archivado el 24 de abril de 2008 en Wayback Machine  - MSDN Library
  14. SetProcessAffinityMask Archivado el 25 de marzo de 2008 en Wayback Machine  - MSDN Library
  15. Notas de la versión de la API Thread Affinity . desarrolladores.apple.com _ Consultado el 27 de mayo de 2020. Archivado desde el original el 9 de abril de 2012.
  16. pbind(1M) Archivado el 25 de febrero de 2021 en la página del manual de Wayback Machine  - Solaris
  17. processor_bind(2) Archivado el 3 de septiembre de 2016 en la página del manual de Wayback Machine  - Solaris
  18. pset_bind(2) Archivado el 20 de enero de 2022 en Wayback Machine  - Biblioteca de información de Oracle Solaris 11.1 - páginas man sección 2
  19. lgrp_affinity_get(3LGRP) Archivado el 10 de junio de 2016 en Wayback Machine  - Guía del desarrollador de optimización de ubicación de subprocesos y memoria
  20. 1 2 Umesh Prabhakar Gaikwad; Kailas S. Zadbuke. Afinidad de procesador en AIX (16 de noviembre de 2006). Consultado el 27 de mayo de 2020. Archivado desde el original el 2 de marzo de 2020.
  21. Comando bindprocessor . IBM . Consultado el 27 de mayo de 2020. Archivado desde el original el 2 de marzo de 2020.
  22. Subrutina bindprocessor . IBM . Consultado el 27 de mayo de 2020. Archivado desde el original el 2 de marzo de 2020.
  23. Guía técnica de IBM zEnterprise 196. Bill White, Erik Bakker, Parwez Hamid, Octavian Lascu, Fernando Nogal, Frank Packeiser, Vicente Ranieri Jr., Karl-Erik Stenfors, Esra Ufacik, Chen Zhu, IBM Redbooks. octubre de 2011
  24. Discusión de desarrolladores