Multiplataforma multiproceso: ¿cuáles son los verdaderos desafíos?

21

Si bien una biblioteca como SDL proporciona una API de envoltura multiplataforma para subprocesos, creo que sería ingenuo suponer que esto conduce directamente al desarrollo fácil de juegos en plataformas muy diferentes (escritorio / móvil).

¿Cuál es la mejor manera de abordar el desarrollo de esta manera (dada cualquier API de subprocesamiento multiplataforma) teniendo en cuenta lo siguiente:

  • diferentes números de núcleos
  • capacidades de procesamiento muy diferentes por núcleo
  • Una arquitectura de sistemas generalmente diferente con, p. diferentes latencias para caché, RAM y acceso de E / S

Tengo la sensación de que la única forma de hacerlo es evaluar cuántos subprocesos se pueden ejecutar por cada dispositivo que pretenda admitir, y descubrir cuál es el mínimo común denominador. Sin embargo, esto todavía me deja en la oscuridad en cuanto a la cantidad total de procesamiento disponible. ¿Estoy en lo cierto al suponer que la única forma de hacer esto de manera efectiva es desarrollar activamente para el dispositivo móvil de menor especificación que pretendo admitir, durante todo el desarrollo? - es decir, el mínimo común denominador? ¿Esto debería ser más o menos suficiente? ¿O hay algo más que esto?

EDITAR: Por favor, ¿podrían otros ofrecer más experiencia en esto ya que no creo que mi pregunta haya sido respondida completamente todavía?

Ingeniero
fuente
Como mi respuesta no responde completamente a su pregunta, ¿podría detallar lo que falta / lo que quiere saber? Puede que no sea un gran escritor, pero he manejado este tipo de problema más de una vez.
Valmond
Realmente no ha respondido la pregunta, que trataba sobre las dificultades de subprocesamiento múltiple y cómo superarlas cuando se desarrolla para plataformas con diferentes capacidades de subprocesamiento . Vea mi párrafo debajo de las viñetas. Hablas de tamaños y resoluciones de pantalla, que no tienen nada que ver con mi pregunta, lee el título.
Ingeniero
1
Supongo que la dificultad proviene de para qué quieres usar los hilos. Una cosa es tener un subproceso auxiliar que haga algo en el lateral, y completamente diferente tratar de exprimir los últimos bits de rendimiento de una máquina de 8 núcleos. A mi modo de ver, los subprocesos SDL están destinados principalmente a la primera, No lo último.
Jari Komppa

Respuestas:

11

Hablas de "dificultades de subprocesos múltiples", pero ¿de qué dificultades estás hablando realmente? En cierto modo, estás citando un problema fantasma que puede no existir. El verdadero desafío es uno que se haga por sí mismo: si está absolutamente decidido a obtener la última gota de energía de una pieza de hardware, eso implica utilizar el hardware para obtener el mejor efecto, pero eso también amplía la brecha entre la máquina más poderosa y el menos poderoso. La implicación de esto es que si tienes un juego que realmente aprovecha al máximo una PS3 (por ejemplo), de todos modos no puedes ejecutarlo en un teléfono celular barato, así que tu problema ya no es "¿cómo puedo obtener 1 programa? para trabajar en hardware muy diferente "pero se convierte en" ¿cómo puedo implementar 1 idea de juego de varias maneras diferentes para que funcione en hardware con potencia diferente?

Si bien una biblioteca como SDL proporciona una API de envoltura multiplataforma para subprocesos, creo que sería ingenuo suponer que esto conduce directamente al desarrollo fácil de juegos en plataformas muy diferentes (escritorio / móvil).

Fácil desarrollo de juegos: seguro. Multithreading óptimo, no. Pero no necesitas multihilo para hacer juegos. Para hacer unos de alto rendimiento, sin duda ayuda. Pero muchos juegos geniales se ejecutan en un solo hilo.

¿Cuál es la mejor manera de abordar el desarrollo de esta manera (dada cualquier API de subprocesamiento multiplataforma) teniendo en cuenta lo siguiente:

  • diferentes números de núcleos
  • capacidades de procesamiento muy diferentes por núcleo
  • Una arquitectura de sistemas generalmente diferente con, p. diferentes latencias para caché, RAM y acceso de E / S

En lugar de intentar asignar sistemas a subprocesos, asigne tareas a subprocesos. Dele a cada tarea los datos que necesita para ejecutar y agrúpelas a cualquier hardware disponible. Por lo general, tendrá algún tipo de grupo de subprocesos para abstraer los diversos núcleos o procesadores, y un administrador de tareas que tiene una cola de tareas y los entrega a los diversos subprocesos cuando el subproceso indica que ha terminado la tarea anterior y está Listo para uno nuevo. El hardware con más núcleos obviamente completará las tareas más rápidamente y podrá renderizar más rápidamente. La especialización de este sistema para que funcione de manera óptima en sistemas con diferentes características se convierte en un problema de optimización avanzada, pero puede basarse en ciertas heurísticas (por ejemplo, una tarea que no funciona).

Sin embargo, la descomposición de las características del juego en tareas discretas es un asunto bastante complejo y, a menudo, no vale la pena el esfuerzo a menos que esté muy seguro de que necesita el rendimiento, por lo que la mayoría ni siquiera lo intentará.

Algunas lecturas adicionales:

http://www.gamasutra.com/view/feature/1830/multithreaded_game_engine_.php - vea la sección 'datos paralelos'. Con este modelo, los datos se dividen en varias tareas idénticas y se distribuyen en subprocesos individuales.

http://software.intel.com/en-us/articles/designing-the-framework-of-a-parallel-game-engine/ - bastante denso, describe cosas a nivel del sistema operativo en lugar del nivel del juego.

http://drdobbs.com/high-performance-computing/216500409 : no es específico del juego, pero es completamente relevante en términos de decirle cómo debe dividir las tareas.

http://www.itfgaming.com/news/tech-focus-crysis-2-and-the-future-of-cryengine-3 - a mitad de esta entrevista hay una anécdota sobre cómo migraron a un sistema basado en tareas .

Kylotan
fuente
Muy buenos puntos. Y es cierto, usé la palabra "dificultades" cuando "desafíos" serían más precisos. Usted dijo: "La descomposición de las características del juego en tareas discretas es un asunto bastante complejo y a menudo no vale la pena el esfuerzo a menos que esté muy seguro de que necesita el rendimiento, por lo que la mayoría ni siquiera lo intentará". ¿Puedes dar más detalles sobre esto? Proporcionar fuentes? Es un poco vago, pero diría que estás llegando al meollo del asunto allí.
Ingeniero
Lo siento, pensé que este tipo de enfoque era bien conocido. Explicaré la respuesta.
Kylotan
4

Cuando hice juegos para móviles, primero desarrollamos una versión 'dorada' (es decir, un juego completamente funcional) y luego la dividimos en 3 versiones principales (pantalla grande, tamaño mediano y pantalla pequeña). Estos se convirtieron aún más en 11 versiones: gráficos exigentes (la lectura requiere mucha memoria / CPU) versus perfil bajo, etc. (también hubo un par de versiones de plataforma especiales).

El mayor problema era (ese era mi trabajo, entre otros) aislar las plataformas necesarias y determinar esas versiones y cómo crearlas (es decir, pantalla grande pero perfil bajo debería ser una versión degradada de pantalla grande / perfil alto o debería ser ¿Pantalla de tamaño medio / perfil lo hizo pantalla grande?).

Por supuesto, codificamos con esto en mente, por lo que los juegos estaban muy unidos al tamaño de la pantalla.

HTH

[editar] Lo que quise decir es que necesitas dividir tus plataformas objetivo en diferentes calidades (es decir, 1 núcleo, 2 núcleos, 1 núcleo pero el doble de rápido ...) Luego, decide cuántos objetivos virtuales quieres (por ejemplo, " solo un "o" Bajo, Medio, Hola ") Luego coloque todas las plataformas en sus respectivas 'calidad' y para cada calidad, tome el denominador más bajo y 'transfiera' el código para que cumpla con esos requisitos (es decir, funciona y es rápido suficiente).

Puede parecer que debe hacer esto con muchas conjeturas, pero ya puede encontrar la peor calidad con la peor plataforma. Elegiría cada próxima cualidad al menos "dos veces tan buena" como la anterior, esto probablemente no generaría más de 3 a 4 "cualidades". Si el código se transfiere desde una versión dorada, cualquier plataforma que no funcione lo suficientemente bien podría retroceder a una 'calidad' más baja para acelerarla. Cualquier plataforma nueva también podría colocarse fácilmente en la calidad adecuada.

Valmond
fuente
Fuera de la cabeza, ¿cuánto tiempo de carga diría que tuvo el proyecto tanto en las fases de diseño como de desarrollo, para acomodar una versión multiplataforma como esta? Solo un promedio aproximado ayudaría.
Ingeniero
1
Bueno, como lo hicimos en varios idiomas (inglés, francés, español, portugués, alemán e italiano en un paquete + cualquier idioma que se necesitara al día, taiwanés, turco, ruso ...) y teníamos nuevas plataformas que necesitábamos para "portar" todos nuestros juegos a cada pocos meses (lea una nueva clase de móviles) realmente hubiéramos perdido mucho tiempo sin ir de esta manera, realmente hubiera sido imposible en realidad sin un gran tem. El diseño del 'marco' se realizó sobre la marcha cuando aprendí sobre diferentes móviles y llegó a la madurez después de unos 3-4 años. Sin embargo, una inversión que vale la pena.
Valmond
1

Tengo la sensación de que la única forma de hacerlo es evaluar cuántos subprocesos se pueden ejecutar por cada dispositivo que pretenda admitir, y descubrir cuál es el mínimo común denominador.

No necesariamente: puede haber esperanza para una solución más dinámica, pero esto depende del problema real que esté tratando de resolver (si lo hay). Eres un poco vago en tu pregunta, así que mi respuesta también debe ser vaga.

Si la agrupación de plataformas en las que tiene la intención de ejecutar tiene la capacidad de enumerar el hardware a través de una API, puede usar esa interfaz para detectar la cantidad máxima de subprocesos que el sistema puede manejar, y usar eso como base para la cantidad de subprocesos de su aplicación debería crear. El único desafío aquí es encontrar esas API; ya sea que vaya o no al nivel del sistema operativo, o busque una biblioteca de terceros, o un SDK / API multiplataforma depende de usted y depende de las plataformas que está tratando de admitir.

¿Cuál es la mejor manera de abordar el desarrollo de esta manera (dada cualquier API de subprocesamiento multiplataforma) teniendo en cuenta lo siguiente:

different numbers of cores
vastly different processing capabilities per core
A generally different systems architecture with eg. different

latencias para caché, RAM y acceso de E / S

En mi opinión, ninguna de esas cosas debería ser su preocupación. Tu preocupación debería ser construir tu juego. Si se topa con un cuello de botella y decide que sería mejor generar un subproceso separado para una tarea específica de procesador intensivo, genere el subproceso y deje que el sistema operativo y otro software de nivel inferior decidan cómo manipular el hardware para manejar el subproceso.

Cifrar
fuente