¿Cuánto ensamblaje se usa realmente en el código del juego moderno? [cerrado]

21

En promedio, ¿con qué frecuencia se usa el ensamblaje en el código del juego moderno?

Específicamente en plataformas que ya tienen buenos compiladores de C ++, como x86, PPC o ARM, porque supongo que los juegos en sistemas integrados hacen un uso extensivo del ensamblaje.

Legión
fuente
44
C ++ no se compila para ensamblar, se compila para el código de máquina. El lenguaje ensamblador es una forma de especificar directamente exactamente qué código de máquina desea generar.
Kylotan
66
C ++ (en general) no se compila realmente para ensamblar, se compila directamente en código máquina. La pregunta probablemente se refiere a cuánto ensamblaje escrito a mano está vinculado a un proyecto o escrito como ensamblaje en línea.
1
De todos modos, no creo que haya una respuesta práctica y útil a esta pregunta. Básicamente depende de factores similares, muchos de los cuales son subjetivos (es decir, las opiniones de los autores del código).
1
No tanto por escrito montaje es importante en estos días, con algunas excepciones como la programación SPU, pero ser capaz de leer es importante para el análisis de volcado de sucesos
Maik Semder
44
@Legion: puede hacer que el compilador / IDE emita ensamblaje, pero eso no significa que el compilador produzca ensamblaje como parte de un proceso de compilación normal. No es necesario que lo haga y, en consecuencia, la mayoría no lo hace.

Respuestas:

29

La respuesta depende un poco de lo que quiere decir con "juego" y de "usado". Asumiré que "usado" significa "escrito durante el curso del proyecto de juego específico".

En mi experiencia y datos anecdóticos de personas con las que he hablado:

  • en juegos basados ​​en navegador? Ninguna.
  • en juegos de PC típicos? Ninguna. (Pero puede ver algunas en bibliotecas de bajo nivel).
  • en juegos iOS y Android? Ninguna.
  • ¿Juegos de PC y juegos de consola "AAA"? Tal vez un poco, tal vez 0.05% de la base del código. (Con un poco más en las bibliotecas).

El conocimiento del lenguaje ensamblador no se espera para el trabajo en la industria de los juegos, pero dependiendo del tipo de juegos que realice, puede ser ventajoso.

Solía ​​haber un argumento de que el compilador hace un mejor trabajo para optimizar el código C que un humano con un ensamblaje escrito a mano. Por lo general, eso es cierto, a veces es falso. Pero en estos días, una combinación de la creciente complejidad de la CPU y la necesidad de escalar gradualmente (es decir, separar los procesadores) significa que los esfuerzos de optimización generalmente se gastan en otros lugares.

En los últimos años, la única vez que he visto el ensamblaje en el código del juego fue en __asm int 3declaraciones para forzar puntos de interrupción, y mi único uso personal del ensamblaje fue mirar el desmontaje de una función para diagnosticar errores de bloqueo inusuales.

Kylotan
fuente
1
¿Qué pasa con las instrucciones de SSE?
Legión
44
@Legion, las personas suelen escribir código SSE utilizando intrínsecos o bibliotecas matemáticas que envuelven el material SSE, o en un mini-lenguaje especializado diseñado específicamente para compilar a SSE, como ispc . Escribir ensamblaje directamente sigue siendo bastante raro.
Nathan Reed
1
Con respecto a los juegos de iOS: si no recuerdo mal, la biblioteca 3D / Math Oolong usó un ensamblaje ARM en línea. Eso ya no es necesario desde que Apple lanzó el marco Accelerate.
Nicolas Miari
De acuerdo con Nathan: SSE y optimizaciones específicas de instrucciones similares generalmente existen dentro de las bibliotecas (ya que generalmente son los únicos lugares donde el beneficio total obtenido vale la pena el esfuerzo puesto).
Kylotan
26

La mayor parte del código de alto rendimiento en los juegos de consola modernos se escribe utilizando una especie de punto medio entre el ensamblaje y C ++: intrínsecos del compilador . Estas construcciones se ven y analizan como funciones de C ++, pero en realidad se traducen en instrucciones de máquina única . Entonces, por ejemplo, mi "sujetar cada valor del vector V para que sea> = a y <= b" se ve como

// for each v.x, ensure v.x >= a.x && v.x <= b.x
inline __m128 ClampSIMD( const __m128 &v, const __m128 & a, const __m128 & b )
{
    return _mm_max_ps( a, _mm_min_ps( v, b ) );
}

En funciones como estas, sigo pensando en términos de las instrucciones específicas de la máquina. , pero tengo la conveniencia de escribirlas en C para no tener que preocuparme por registrar el color y la programación, cargar operaciones y otros detalles aburridos.

Todavía necesita saber qué instrucciones admite la CPU, especialmente porque los compiladores modernos son terribles para vectorizar código, en comparación con lo bien que un humano inteligente puede hacer el trabajo. También, a veces, los detalles sutiles de cómo organizar su código pueden tener enormes implicaciones para el rendimiento que no son obvias sin comprender lo que está haciendo la máquina.

Aunque es posible que no codifiquemos en el ensamblaje, todavía depuramos mucho en el ensamblado. La optimización de los compiladores reorganiza agresivamente el código de manera que los depuradores no puedan seguir el ritmo, por lo que a menudo, al depurar un "modo de lanzamiento", lo mejor es abrir el desensamblador y rastrear el código de esa manera. Esta charla de GDC sobre "Depuración forense" de bloqueos ilustra muchos de los por qué y cómo de la depuración a ese nivel.

Crashworks
fuente
3
+1 simplemente porque Crashworks es bien conocido en SO como "ese tipo que escribe código optimizado de bajo nivel para juegos" , si alguien sabe sobre este tema, es él.
BlueRaja - Danny Pflughoeft
@ BlueRaja-DannyPflughoeft "Bien conocido"? ¡Me halaga! =) Una coincidencia divertida, a la luz de los comentarios de Nathan Reed, es que aprendí muchas de mis habilidades de optimización de bajo nivel en Naughty Dog.
Crashworks
En otros lugares también he escuchado la importancia del ensamblaje en la depuración. Entonces voy a aprenderlo. Gracias por la información y los enlaces.
Legion
7

Los problemas que solían requerir un ensamblaje laminado a mano son cada vez menos numerosos. Lo que "podría" ganar en velocidad lo pierde en legibilidad y la capacidad de depurar. También debe hacerse solo como uno de los últimos pasos de optimización en secciones de código, ya que en la mayoría de los casos los problemas de velocidad no son algo que no pueda mejorarse con el ensamblaje. En estos días, las CPU se han vuelto mucho más rápidas que las velocidades de memoria, a menudo es más importante controlar cómo fluyen los datos a través de la CPU que cualquier otra cosa.

Con los compiladores modernos también les resulta difícil optimizar el código de ensamblaje, ya que tienen que lidiar con los registros que haya tocado y, por lo general, no pueden volver a ordenar las instrucciones en su código creado a mano. Para reducir la necesidad de ensamblaje, ahora también hay intrínsecos que ayudan a obtener acceso a conceptos de bajo nivel, pero de una manera que es fácil de compilar y les permite trabajar con usted en lugar de en contra.

Dicho esto, la SPU en la PS3 es un área donde las personas todavía tienen que usar el ensamblaje para aprovechar al máximo el procesador, con instrucciones manuales, por ejemplo, como se explica aquí .

Roger Perkins
fuente
1
Incluso en PS3, la gente suele hacer no bastante programa en el montaje desnudo. Hay una herramienta que le permite escribir código en una sintaxis similar a un ensamblaje, donde especifica las instrucciones de la máquina, pero realiza la asignación de registros, la programación de instrucciones y la canalización de bucles por usted. Bueno, tal vez Naughty Dog realmente lo hace todo a mano, pero incluso la mayoría de los desarrolladores de PS3 SPU no lo hacen en mi experiencia. :)
Nathan Reed
1
@NathanReed En los días de PS2, la canalización de bucle manual era en realidad parte de la entrevista del programador de Naughty Dog.
Crashworks
-1

El hecho es que vivimos en un mundo multiplataforma, y ​​algunas partes de nuestro código de juego deben adaptarse a la plataforma local; bueno, no es necesario, ¡pero hay beneficios si aprovechamos el hardware local!

No se trata de juegos o lógica de juegos, se trata de la ubicación del hardware para un rendimiento óptimo del código sobre el que depende la lógica del juego, de hecho podemos envolver secciones de código, por ejemplo, usando macros, de modo que haya un código fuente, que se ejecute bien en el plataforma contra la que fue construida.

Homero
fuente