threads thread sincronizar programa multi manejo hilos entre eliminar ejemplos detener definicion comunicacion multithreading concurrency multicore

multithreading - thread - programa de hilos en python



¿Por qué los programas grandes(como los juegos) no usan muchos hilos diferentes? (10)

Además de los desafíos técnicos de la programación para núcleos múltiples, los juegos comerciales tienen que funcionar bien en sistemas de gama baja sin núcleos múltiples para ganar dinero.

Ahora que los procesadores multi-núcleo han estado funcionando por un tiempo y las consolas de juegos más importantes tienen múltiples núcleos, es solo cuestión de tiempo antes de que aparezca el doble núcleo en la lista de requisitos mínimos del sistema para juegos de PC.

Aquí hay un enlace a una entrevista con Orion Granatir de Intel, donde habla sobre hacer que los desarrolladores de juegos aprovechen el multihilo.

No sé cómo funcionan mucho los juegos comerciales, pero los juegos de código abierto con los que me he cruzado no parecen estar muy conectados. Lo mismo ocurre con la mayoría de las otras aplicaciones de escritorio, normalmente se utilizan dos o tres subprocesos (por ejemplo, lógica de programa y actualizaciones de GUI).

¿Por qué los juegos no tienen muchos hilos? Por ejemplo, hilos separados para física, sonido, gráficos, inteligencia artificial, etc.


El hecho de que todos digan correctamente que el multihilo es duro es muy triste. Necesitamos desesperadamente hacer que los sistemas de concurrencia sean fáciles.

Personalmente, creo que vamos a necesitar un cambio de paradigma y nuevas herramientas.


Es muy difícil utilizar subprocesos sin problemas, y la mayoría de las API de GUI se basan en la codificación controlada por eventos de todos modos. Los subprocesos exigen el uso de mecanismos de bloqueo que agreguen demora al código, y con frecuencia ese retraso es impredecible dependiendo de quién sostiene el candado en ese momento.

Me parece sensato tener un solo (o tal vez muy pocos) hilos que manejen las cosas de una forma guiada por eventos en lugar de cientos de hilos que causan errores extraños e irrepetibles.


Estaba a punto de publicar lo mismo que William, pero me gustaría ampliarlo un poco. Es muy difícil escribir un código óptimo para el futuro. Dada la opción entre escribir algo que se escalará al hardware que no tiene, o escribir algo que funcionará en el hardware que tiene, la mayoría de las personas optará por lo último. Dado que el paradigma de un solo núcleo ha estado con nosotros durante tanto tiempo, la mayoría de los códigos que se han escrito (especialmente para los juegos en los que existe una presión extrema para que salga la puerta) no son una prueba de futuro.

x86 ha sido muy amable con los programadores de juegos, ya que no hemos tenido que pensar en las ramificaciones de las plataformas de hardware menos permisivas.


Hay muchos problemas con las condiciones de carrera y el bloqueo de datos cuando se usan muchos hilos. Dado que las diferentes partes de los juegos son bastante dependientes entre sí, no tiene mucho sentido hacer toda la ingeniería adicional necesaria para usar un montón de hilos.


La razón principal es que, por muy elegante que suene, utilizar múltiples hilos en un programa tan complicado como un juego en 3D es realmente, realmente, muy difícil. Además, antes de la introducción relativamente reciente de los sistemas multi-core de bajo costo, el uso de múltiples hilos no ofrecía mucho de un incentivo de rendimiento.


Muchos juegos actualmente usan sistemas de "tareas" o "trabajos" para el procesamiento paralelo. Es decir, el juego genera un número fijo de subprocesos de trabajo que se utilizan para tareas múltiples. El trabajo se divide en pequeños fragmentos y se pone en cola, luego se envía para ser procesado por los hilos de trabajo a medida que estén disponibles.

Esto se está volviendo especialmente común en las consolas. La PS3 se basa en la arquitectura de la celda, por lo que debe usar el procesamiento en paralelo para obtener el mejor rendimiento del sistema. Xbox 360 puede emular una configuración de tareas / tareas diseñada para PS3 ya que tiene múltiples núcleos. Probablemente, para la mayoría de los juegos, la mayoría del diseño del sistema se compartirá entre las bases de código de 360, PS3 y PC, por lo que es muy probable que las PC utilicen el mismo tipo de táctica.

Si bien es difícil escribir un código seguro, como lo indican muchas de las otras respuestas, creo que hay otras razones más por las cosas que estás viendo:

  • Primero, muchos juegos de código abierto tienen algunos años. Especialmente con esta generación de consolas, la programación paralela se está volviendo popular e incluso necesaria como se mencionó anteriormente.
  • En segundo lugar, muy pocos proyectos de código abierto parecen preocupados por obtener el mayor rendimiento posible. Como John Carmack señaló en el proyecto GLX de Utah, el código altamente optimizado a menudo es más difícil de mantener que el código no optimizado, por lo que este último generalmente sería el preferido en contextos de fuente abierta.
  • Tercero, no tomaría una pequeña cantidad de hilos creados por un juego para significar que no está usando trabajos paralelos bien.

Necesita pensar, ¿cuáles son los beneficios reales de los hilos? Recuerde que en una máquina de núcleo único, los hilos no permiten la ejecución simultánea, solo la impresión de ello. Detrás de escena, la CPU está cambiando de contexto entre los diferentes hilos, haciendo un poco de trabajo en cada uno cada vez. Por lo tanto, si tengo varias tareas que no implican esperar, ejecutarlas al mismo tiempo (en un solo núcleo) no será más rápido que ejecutarlas de forma lineal. De hecho, será más lento, debido a la sobrecarga adicional de la frecuente conmutación de contexto.

Si ese es el caso, entonces, ¿por qué utilizar hilos en una sola máquina central? Bueno, en primer lugar, porque a veces las tareas pueden implicar largos períodos de espera en algún recurso externo, como un disco u otro dispositivo de hardware, para estar disponibles. Mientras que la tarea está en una etapa de espera, el enhebrado permite que otras tareas continúen, utilizando así el tiempo de la CPU más eficiente.

En segundo lugar, las tareas pueden tener un plazo de algún tipo para completar, especialmente si responden a un evento. El ejemplo clásico es la interfaz de usuario de una aplicación. La computadora debe responder a los eventos de acción del usuario lo más rápido posible, incluso si está ocupado realizando alguna otra tarea de larga ejecución, de lo contrario, el usuario se agitará y puede creer que la aplicación se ha bloqueado. Enhebrar permite que esto suceda.

En cuanto a los juegos, no soy un programador de juegos, pero mi comprensión de la situación es la siguiente: los juegos en 3D crean un modelo programático del mundo del juego; jugadores, enemigos, objetos, terreno, etc. Este mundo del juego se actualiza en pasos discretos, según la cantidad de tiempo transcurrida desde la actualización anterior. Entonces, si 1ms ha pasado desde la última vez en el ciclo del juego, la posición de un objeto se actualiza usando su velocidad y el tiempo transcurrido para determinar el delta (obviamente, la física es un poco más complicada que eso, pero obtienes la idea). Otros factores como la IA y las claves de entrada también pueden contribuir a la actualización. Cuando todo está terminado, el mundo del juego actualizado se representa como un nuevo marco y el proceso comienza de nuevo. Este proceso generalmente ocurre muchas veces por segundo.

Cuando pensamos en el ciclo del juego de esta manera, podemos ver que el motor está logrando un objetivo muy similar al del enhebrado. Tiene una serie de tareas de larga ejecución (actualización de la física mundial, manejo de la entrada del usuario, etc.), y da la impresión de que están sucediendo al mismo tiempo dividiéndolas en pequeños pedazos de trabajo e intercalando estas piezas, pero en lugar de confiar en la CPU o el sistema operativo para administrar el tiempo dedicado a cada uno, lo está haciendo él mismo. Esto significa que puede mantener todas las diferentes tareas sincronizadas correctamente y evitar las complejidades que conlleva el enhebrado real: bloqueos, prioridad, reentrada, etc. No hay implicancia en el rendimiento de este enfoque tampoco, porque como dijimos La máquina de un solo núcleo realmente solo puede ejecutar código linealmente de todos modos.

Las cosas cambian cuando tienen un sistema multi-core. Ahora, las tareas pueden ejecutarse de manera genuina concurrente y puede haber un beneficio en el uso del subprocesamiento para manejar diferentes partes de las actualizaciones del mundo del juego, siempre que podamos sincronizar los resultados para generar marcos consistentes. Por lo tanto, esperaríamos que con el advenimiento de los sistemas multi-core, los desarrolladores de motores de juegos estarían trabajando en esto. Y así resulta, lo son. Valve, los creadores de Half Life, han introducido recientemente el soporte de múltiples procesadores en su Source Engine, y me imagino que muchos otros desarrolladores de motores están siguiendo su ejemplo.

Bueno, eso resultó un poco más de lo que esperaba. No soy un experto en juegos de rosca o juegos, pero espero no haber cometido ningún error especialmente evidente. Si tengo, estoy seguro de que la gente me va a corregir :)


No sé sobre los juegos que has jugado, pero la mayoría de los juegos ejecutan el sonido en un hilo separado. Código de red, al menos los escuchas de socket se ejecutan en un hilo separado.

Sin embargo, el resto del motor del juego generalmente se ejecuta en un solo hilo. Hay razones para esto. Por ejemplo, la mayoría del procesamiento en un juego ejecuta una cadena única de dependencias. Los gráficos dependen del estado del motor de física al igual que la inteligencia artificial. Diseñar para múltiples hilos significa que debe tener latencia de cuadro entre los diversos subsistemas para concurrencia. Usted obtiene un tiempo de respuesta más rápido y un juego más ágil si estos subsistemas se calculan linealmente en cada cuadro. La parte del juego que más se beneficia de la paralelización es, por supuesto, el subsistema de renderización que se descarga en tarjetas aceleradoras de gráficos altamente paralelizadas.


Los hilos están muertos, bebé.

De manera realista, en el desarrollo de juegos, los hilos no escalan más allá de la descarga de tareas muy dedicadas, como la creación de redes y la carga. Los sistemas de trabajo parecen ser la única forma de avanzar, dado que 8 sistemas de CPU son cada vez más comunes incluso en PC. Y puede garantizar que los próximos sistemas súper multinúcleo como Larrabee de Intel estarán basados ​​en el sistema de trabajo.

Esta ha sido una realización algo dolorosa en los proyectos de Playstation3 y XBOX360, y parece que ahora incluso Apple se ha sumado a su sistema "revolucionario" Grand Central Dispatch en Snow Leopard.

Los hilos tienen su lugar, pero la ingenua promesa de "poner todo en un hilo y todo funcionará más rápido" simplemente no funciona en la práctica.