Con los programadores de sistemas operativos modernos, ¿sigue teniendo sentido bloquear manualmente los procesos a CPU / núcleos específicos?

StackOverflow https://stackoverflow.com/questions/1602980

Pregunta

Recientemente aprendí que a veces las personas bloquearán procesos o subprocesos específicos a procesadores o núcleos específicos, y se piensa que este ajuste manual distribuirá mejor la carga. Esto es un poco contraintuitivo para mí: creo que el programador del sistema operativo sería capaz de tomar una mejor decisión que un humano acerca de cómo distribuir la carga. Podía ver que fuera cierto para sistemas operativos más antiguos que tal vez no eran conscientes de problemas como la mayor latencia entre pares de núcleos específicos o el caché compartido entre un par de núcleos pero no otro par. Pero supongo que los sistemas operativos "modernos" como Linux, Solaris 10, OS X y Vista deberían tener programadores que conozcan esta información. ¿Estoy equivocado acerca de sus capacidades? ¿Estoy equivocado de que es un problema que el sistema operativo realmente puede resolver? Estoy particularmente interesado en la respuesta para Solaris y Linux.

La consecuencia es si necesito informar o no a los usuarios de mi software (multiproceso) sobre cómo podrían considerar el equilibrio en su caja.

¿Fue útil?

Solución

En primer lugar, 'Bloquear' no es un término correcto para describirlo. "Afinidad" es el término más adecuado.

En la mayoría de los casos, no es necesario preocuparse por ello. Sin embargo, en algunos casos, la configuración manual de la afinidad de CPU / proceso / subproceso podría ser beneficiosa .

Los sistemas operativos suelen ser ajenos a los detalles de la arquitectura moderna multinúcleo. Por ejemplo, supongamos que contamos con procesadores Quadcore de 2 zócalos, y el procesador admite SMT (= HyperThreading ). En este caso, tenemos 2 procesadores, 8 núcleos y 16 hilos de hardware. Así, OS verá 16 procesadores lógicos. Si un sistema operativo no reconoce dicha jerarquía, es muy probable que pierda algunas mejoras de rendimiento. Las razones son:

  1. Caches : en nuestro ejemplo, dos procesadores diferentes (instalados en dos sockets diferentes) no comparten ningún caché en el chip. Digamos que una aplicación tiene 4 subprocesos de ejecución ocupada y una gran cantidad de datos son compartidos por subprocesos. Si un sistema operativo programa los subprocesos entre los procesadores, es posible que perdamos alguna localidad de caché, lo que resulta en una pérdida de rendimiento. Sin embargo, los subprocesos no comparten muchos datos (tienen un conjunto de trabajo distinto), por lo que la separación a diferentes procesadores físicos sería mejor al aumentar la capacidad efectiva de caché. Además, podría darse un escenario más complicado, lo que es muy difícil para el sistema operativo tener en cuenta.

  2. Conflicto de recursos : consideremos el caso SMT (= HyperThreading). SMT comparte muchos recursos importantes de CPU, como cachés, TLB y unidades de ejecución. Digamos que solo hay dos hilos ocupados. Sin embargo, un sistema operativo puede programar estúpidamente estos dos subprocesos en dos procesadores lógicos desde el mismo núcleo físico. En tal caso, dos recursos lógicos sostienen recursos significativos.

Un buen ejemplo es Windows 7. Windows 7 ahora admite una política de planificación inteligente que considera SMT ( artículo relacionado ). Windows 7 en realidad previene el 2. caso anterior. Aquí hay una instantánea del administrador de tareas en Windows 7 con un 20% de carga en Core i7 (quadcore con HyperThreading = 8 procesadores lógicos):

 texto alternativo
(fuente: egloos.com )

El historial de uso de la CPU es muy interesante, ¿no? :) Puede ver que solo se utiliza una sola CPU en pares , lo que significa que Windows 7 evita programar dos subprocesos en un mismo núcleo simultáneamente como sea posible. Esta política definitivamente reducirá los efectos negativos de SMT, como el conflicto de recursos.

Me gustaría decir que el sistema operativo no es muy inteligente para entender la arquitectura moderna de múltiples núcleos donde hay muchos cachés, caché de último nivel compartido, SMT e incluso NUMA. Por lo tanto, podría haber buenas razones por las que deba configurar manualmente la afinidad de CPU / proceso / subproceso.

Sin embargo, no diré que esto es realmente necesario. Solo cuando entienda completamente sus patrones de carga de trabajo y la arquitectura de su sistema, pruébelo. Y, vea los resultados si su intento es efectivo.

Otros consejos

Para aplicaciones de propósito general, no hay razón para configurar la afinidad de la CPU; simplemente debe permitir que el programador del SO elija qué CPU debe ejecutar el proceso o subproceso. Sin embargo, hay casos en los que es necesario establecer la afinidad de la CPU. Por ejemplo, en sistemas en tiempo real donde el costo de migrar un subproceso de un núcleo a otro (que puede ocurrir en cualquier momento si no se ha establecido la afinidad de la CPU) puede introducir retrasos impredecibles que pueden hacer que las tareas no cumplan con sus plazos y que excluye las garantías en tiempo real.

Puede consultar este artículo acerca de una implementación de varios núcleos de CORBA en tiempo real que, entre otras cosas, tenía que establecer la afinidad de la CPU para que la migración de la CPU no pudiera dar lugar a plazos no cumplidos.

El documento es: Rendimiento en tiempo real y middleware para multiprocesador y plataformas multinúcleo de Linux

Para aplicaciones diseñadas con paralelismo y múltiples núcleos en mente, la afinidad de subprocesos predeterminada del sistema operativo a veces no es suficiente. Hay muchos enfoques para el paralelismo, pero hasta ahora todos requieren la participación del programador y el conocimiento, al menos en algún nivel, de la arquitectura en la que se mapeará la solución. Esto incluye las máquinas, las CPU y los subprocesos que están involucrados.

Este es un tema investigado activamente, y hay un excelente curso sobre OpenCourseWare de MIT que profundiza en estos temas: http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-189January--IAP --2007 / CourseHome /

Bueno, algo que mucha gente no ha pensado aquí es la idea de prohibir que se ejecuten dos procesos en el mismo procesador (socket). Podría valer la pena ayudar al sistema a vincular diferentes procesos muy utilizados a diferentes procesadores. Esto puede evitar la contención si el programador no es lo suficientemente inteligente como para resolverlo por sí mismo.

Pero esta es más una tarea de administración del sistema que una para los programadores. He visto optimizaciones como esta para algunos servidores de bases de datos de alto rendimiento.

La mayoría de los sistemas operativos modernos harán un trabajo efectivo de asignación de trabajo entre núcleos. También intentan mantener los subprocesos ejecutándose en el mismo núcleo, para obtener los beneficios de caché que mencionó.

En general, nunca debes configurar la afinidad de tu hilo a menos que tengas una buena razón para hacerlo. No tiene una visión tan buena como el sistema operativo en el otro trabajo que hacen los hilos en el sistema. Los kernels se actualizan constantemente en función de la nueva tecnología de procesador (CPU única por socket para hipervínculos a múltiples núcleos por socket) Cualquier intento de establecer una afinidad difícil puede ser contraproducente en futuras plataformas.

Este artículo de la revista MSDN, Uso de la concurrencia para escalabilidad , ofrece una buena visión general de los subprocesos múltiples en Win32. Respecto a la afinidad de CPU,

  

Windows emplea automáticamente   llamada afinidad de procesador ideal en   un intento de maximizar el caché   eficiencia. Por ejemplo, un hilo   corriendo en la CPU 1 que obtiene contexto   desconectado preferirá correr de nuevo   en la CPU 1 con la esperanza de que algunos de sus   Los datos aún residirán en el caché. Pero   Si la CPU 1 está ocupada y la CPU 2 no, la   hilo podría ser programado en la CPU 2   en cambio, con todo el caché negativo   Efectos que implica.

El artículo también advierte que la afinidad de la CPU no debe manipularse sin una comprensión profunda del problema. Según esta información, mi respuesta a su pregunta sería No, excepto en casos muy específicos y bien entendidos.

Ni siquiera estoy seguro de que puedas anclar procesos a una CPU específica en Linux. Por lo tanto, mi respuesta es " NO " - deje que el sistema operativo lo maneje, es más inteligente que usted la mayor parte del tiempo.

Editar: Parece que en win32 tienes cierto control sobre qué familia de CPU vas a ejecutar este proceso. Ahora solo espero que alguien me demuestre que estoy equivocado también en linux / posix ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top