¿Cuándo un motor de tareas paralelas se convierte en una buena solución?

8

A menudo tengo la tentación de romper el juego en el que estoy trabajando para probar una arquitectura basada en tareas paralelas, pero eso no parece ser un gran requisito para mi proyecto, así que lo evito por el momento. Estoy planeando probarlo primero en un proyecto de juguete, para "jugar con el concepto".

Ahora, lo que pregunto es que, dado que muchos juegos (no AAA) no requieren un rendimiento realmente alto, parece que no vale la pena molestarse en usar un motor basado en tareas hasta ... ¿qué casos?

Por el momento, solo supongo que es necesario cuando realmente necesita explotar el máximo rendimiento del hardware (multi-core). ¿Hay otros casos en los que es una buena idea usar un motor basado en tareas? ¿O tal vez, para nuevos proyectos, siempre es bueno comenzar con un motor basado en tareas?

Klaim
fuente

Respuestas:

7

El enhebrado se usa en dos situaciones:

  1. Cuando tiene mucho trabajo que hacer pero necesita que se mantenga la capacidad de respuesta del usuario.
  2. Cuando necesite la potencia de más de un núcleo de procesamiento en su plataforma favorita / requisito mínimo.

Si puede esperar razonablemente que una o ambas de estas cosas sean necesarias, entonces hágalo. De lo contrario, no lo hagas. Por supuesto, nadie te impedirá enhebrar por diversión porque puedes, o hurgar e investigar, pero en términos de hacer hilos por los beneficios de obtener una aplicación multiproceso, entonces los dos casos de uso anteriores son más o menos

DeadMG
fuente
2
+1 para la capacidad de respuesta: uno de los requisitos para mi proyecto principal es no tener pantalla de carga, experiencia continua para una máxima inmersión. Ese es un buen punto.
Klaim
1
+1 exactamente por qué usé múltiples hilos en un juego de rompecabezas: trabajo pesado (verificar millones de combinaciones) sin congelar la interfaz de usuario.
ashes999
"pantalla sin carga, experiencia continua": tendrá que construir toda su arquitectura en torno a esta idea, es un descanso del diseño de "cargar un nivel y jugar en él, luego cargar otro nivel" que utilizan la mayoría de los motores pequeños.
Patrick Hughes
14

Si su juego va a requerir un uso remoto de hardware, entonces necesita hilos para hacer frente a todo el hardware moderno; Las futuras CPU que saldrán en el próximo año o dos están comenzando a hacer 4 núcleos como mínimo y hasta 16 núcleos comunes para los mercados de entusiastas / rendimiento. Si está haciendo subprocesos múltiples, definitivamente haga una arquitectura orientada a tareas, ya que cualquier otro modelo de subprocesamiento está inherentemente roto para los motores de juegos con visión de futuro.

Ahora tenga en cuenta que por "tareas" me refiero a "trabajos" y no a "hilos separados para diferentes subsistemas del motor". Absolutamente no desea hacer algo como tener un hilo de gráficos, un hilo de física, un hilo de IA, etc. Eso no escala más allá de un pequeño puñado de núcleos y de todos modos no le da ningún paralelismo real. La física no debe ejecutar más de una actualización por actualización de IA (desea que su IA pueda reaccionar a los eventos de física), y los gráficos no tienen casi nada nuevo que representar si la física no se ha ejecutado, por lo que cada subsistema se ejecuta naturalmente en secuencia orden. Usted no

Lo que quieres hacer es esto. Crea un carrete de hilo. Ejecute su ciclo de juego con la secuencia clásica de actualizaciones del subsistema. Sin embargo, para cada subsistema, separe la carga de trabajo en lotes separables distintos y distribúyalos al grupo de subprocesos. Espera a que se completen todos los trabajos antes de ejecutar el siguiente estado del ciclo de actualización del juego. Algunos subsistemas pueden tener múltiples subetapas; por ejemplo, los gráficos pueden emitir una serie de trabajos para eliminar y luego una segunda serie de trabajos para realizar la creación de la cola de representación. Este enfoque evita el problema de sincronización del primer enfoque, escala a un número mucho mayor de núcleos y, francamente, es más fácil de codificar, depurar y mantener.

Sean Middleditch
fuente
Gracias por los consejos sobre cómo construir este tipo de motor, pero ya estoy bien documentado, por lo que no fue necesario. Es más la pregunta de "cuándo vale la pena" que hago. Creo que aún es bueno señalar esas informaciones para aquellos que no saben, así que no las eliminen :)
Klaim
Suena muy razonable
Den
Al igual que Apple, una vez que te acostumbras a los trabajos no hay vuelta atrás =) Esta es una buena sugerencia de arquitectura para cualquier motor nuevo.
Patrick Hughes
@SeanMiddleditch ¿No estás simplemente cambiando la granularidad de enhebrar de esa manera? En lugar de solo un subproceso por sistema (que de hecho no es tan escalable, algunos sistemas requieren mucha más energía que otros y también puede haber muchos más sistemas con núcleos disponibles). Por lo tanto, está ajustando la granularidad de los datos sobre los que actúa cada subproceso. No estoy seguro de cómo se desarrollará esto, pero tampoco tengo nada mejor que agregar. ¿Todavía tienes esta opinión después de 7 años? Gracias.
Nikos
1
@ Nik-Lz: no, porque "múltiples subprocesos por sistema" implica que usted sabe cuáles deberían ser los subprocesos por sistema. ¿Deberías tener 2 hilos para renderizar y 3 para física? ¿Cuántos para la IA? ¿No dependería todo eso de la escena específica e incluso en qué parte de la escena está mirando el jugador y qué está sucediendo en el momento? Un sistema de trabajo se adapta dinámicamente fácilmente a las necesidades inmediatas en lugar de agrupar un subproceso completo en un subsistema que puede no necesitarlo en este momento.
Sean Middleditch el
0

Hay dos usos en subprocesos múltiples, uno es mejorar el rendimiento de su programa y el otro es dejar que el programa se ejecute cuando hay un gran proceso en progreso. por ejemplo, cuando intenta cargar algunos datos, le molesta si su programa se cuelga, por lo que puede usar otro hilo para cargar y mantener el hilo principal libre para continuar el ciclo principal. mejorar el rendimiento usando hilos es, por otro lado, algo realmente difícil. ya que usualmente haces todo en un proceso lineal y eso es algo en contraste con el procesamiento paralelo. y siempre tiene que usar su hilo principal para las actualizaciones gráficas del dispositivo que hace que sea aún más difícil dividir las tareas entre hilos.

Ali1S232
fuente
1
Enhebrar no es difícil. :) Es algo que muchas personas nunca aprenden a hacer correctamente, por lo que piensan que es difícil debido a la inexperiencia. Especialmente en los juegos, muchos de los algoritmos y estructuras de datos centrales son bastante fáciles de manejar con múltiples hilos. Las actualizaciones físicas, por ejemplo, se pueden dividir en islas de objetos, y cada una de ellas se distribuye en un hilo diferente para su integración y resolución. Del mismo modo, la eliminación de objetos para gráficos está prácticamente libre de contención de acceso a datos de lectura-escritura.
Sean Middleditch
@seanmiddleditch No dije que usar hilos en sí es algo difícil, pero lograr usar hilos de manera efectiva y equilibrarlos para compartir la misma carga es algo difícil.
Ali1S232