Siempre encontré el término "microoptimización", bastante ambiguo. Si algunos cambios en el nivel de instrucción en el diseño de la memoria y los patrones de acceso hacen algo 80 veces más rápido por parte de un profesional disciplinado que mide sus puntos críticos sin reducir la complejidad algorítmica, ¿es eso una "microoptimización"? Para mí eso es una "megaoptimización" para hacer algo 80 veces más rápido en un caso de uso del mundo real. Las personas tienden a hablar de estas cosas, como que tales optimizaciones tienen efectos microscópicos.
Ya no estoy trabajando en gamedev, pero trabajo en VFX en áreas como el trazado de ruta, y he visto muchas implementaciones de árboles BVH y KD que procesan ~ 0.5 millones de rayos por segundo en una escena compleja (y esto es con evaluación multiproceso). Hablando en términos generales, tiendo a ver una implementación directa de un BVH en un contexto de trazado de rayos a menos de 1 millón de rayos / seg incluso con una evaluación multiproceso. Excepto que Embree tiene un BVH que puede procesar más de 100 millones de rayos en la misma escena con el mismo hardware.
Esto se debe completamente a las "micro optimizaciones" de que Embree es 200 veces más rápido (el mismo algoritmo y estructura de datos), pero, por supuesto, la razón es mucho más rápido porque los desarrolladores de Intel son profesionales que se apoyan en sus perfiladores y medidas y Realmente sintonizado las áreas que importaban. No estaban cambiando el código de todos modos y cometiendo cambios que hicieron 0.000000001% de mejoras a costa de degradar significativamente la mantenibilidad. Estas fueron optimizaciones muy precisas aplicadas en manos juiciosas: podrían haber sido microscópicas en términos de enfoque pero macroscópicas en términos de efecto.
Naturalmente, con los requisitos de velocidad de fotogramas en tiempo real de los juegos, dependiendo de qué tan alto o bajo nivel estés trabajando con el motor del juego (incluso los juegos hechos con UE 4 a menudo se implementan al menos parcialmente en un script de alto nivel, pero no, digamos, las partes más críticas del motor de física), las micro optimizaciones se convierten en un requisito práctico en ciertas áreas.
Otra área muy básica que nos rodea a diario es el procesamiento de imágenes, como desenfocar imágenes de alta resolución en tiempo real y tal vez hacer otros efectos en ellas como parte de una transición que probablemente todos hemos visto en alguna parte, tal vez incluso un efecto de sistema operativo. No puede implementar necesariamente tales operaciones de imagen desde un bucle cero a través de todos los píxeles de una imagen y esperar tales resultados en tiempo real a velocidades de cuadro coincidentes. Si se trata de CPU, generalmente estamos viendo SIMD y algunos microajustes, o estamos viendo sombreadores de GPU que tienden a requerir una mentalidad de nivel micro para escribir de manera efectiva.
En caso afirmativo, a medida que el hardware mejora, ¿deberíamos esperar que los lenguajes de nivel superior se hagan cargo de la industria del juego?
Dudo que los avances de hardware por sí solos puedan hacer eso, porque a medida que avanza el hardware, también lo hacen las instrucciones y la tecnología (por ejemplo, física en la GPU), y las técnicas, y las expectativas de los clientes sobre lo que quieren ver y la competencia. formas que a menudo hacen que los desarrolladores vuelvan a ser de bajo nivel, como en el caso de los desarrolladores web que ahora escriben sombreadores GLSL de bajo nivel en WebGL (el desarrollo web de este tipo en particular podría decirse que es incluso más bajo que hace una década o dos, ya que GLSL es un lenguaje tipo C de nivel extremadamente bajo, y nunca habría adivinado hace una o dos décadas que algunos desarrolladores web aceptarían escribir sombreadores de GPU de bajo nivel).
Si va a haber una manera de que las áreas críticas para el rendimiento se muevan a lenguajes de nivel superior, tendrá que provenir más del software, los compiladores y las herramientas que tenemos disponibles tal como lo veo. El problema para mí en cualquier futuro previsible no es que el hardware no sea lo suficientemente potente. Tiene más que ver con la forma en que no podemos encontrar maneras de hablar con mayor eficacia cada vez que cambia y avanza sin volver a su propio idioma. En realidad, es el rápido ritmo al que cambia el hardware lo que hace que la programación de alto nivel sea bastante difícil de alcanzar para estas áreas, como lo veo, ya que si hipotéticamente nuestro hardware dejara de avanzar de la nada durante las siguientes décadas,
Curiosamente en estos días, cuando estoy trabajando en áreas genuinas de rendimiento crítico, tengo que pensar un poco más bajo que lo que comencé (a pesar de que comencé en la era Borland Turbo C DOS). Porque en aquel entonces el caché de la CPU era casi inexistente. En su mayoría, solo era DRAM y registros, lo que significaba que podía concentrarme más en la complejidad algorítmica y escribir estructuras vinculadas como árboles de una manera muy directa sin tener mucho impacto en el rendimiento. En estos días, los detalles de bajo nivel del caché de la CPU dominan mi pensamiento casi tanto como el algoritmo en sí. Y del mismo modo, tenemos máquinas multinúcleo que deben hacernos pensar en multihilo y atómicos y mutexes y seguridad de subprocesos y estructuras de datos concurrentes, etc., lo que yo diría es, en muchos aspectos, un enfoque de nivel mucho más bajo (como en, no tan humanamente intuitivo) que cuando comencé.
Curiosamente, eso me parece muy cierto ahora. Creo que hoy me impactan más las complejidades subyacentes y de bajo nivel y los detalles del hardware que hace 30 años, haciendo mi mejor esfuerzo para quitarme las gafas de nostalgia. Por supuesto, podríamos haber hablado un poco de ensamblaje aquí y tener que lidiar con algunos detalles sangrientos como XMS / EMS. Pero en su mayor parte, diría que había menos complejidad y conocimiento de hardware y compiladores que requería en aquel entonces de lo que necesito hoy cuando estoy trabajando en áreas críticas de rendimiento. Y eso casi parece cierto para toda la industria si dejamos de lado como escribirif/else
declaraciones de una manera un poco más legible para los humanos y considere cuánto piensan las personas en general en estos días más sobre los detalles de nivel inferior del hardware (desde múltiples núcleos a GPU a SIMD a caché de CPU y los detalles internos de cómo sus compiladores / intérpretes / las bibliotecas funcionan y así sucesivamente).
Nivel alto! = Menos eficiente
Volviendo a esta pregunta:
En caso afirmativo, a medida que el hardware mejora, ¿deberíamos esperar que los lenguajes de nivel superior se hagan cargo de la industria del juego?
Para mí no se trata de hardware. Se trata de optimizadores y herramientas. Cuando comencé, la gente prácticamente escribía todos los juegos de consola en ensamblador, y había una verdadera ventaja de rendimiento, especialmente dada la falta de compiladores de calidad que generaban 6502.
A medida que los compiladores de optimización de C se volvieron más inteligentes en sus optimizaciones, comenzaron a llegar a un punto en el que el código de nivel superior escrito en C rivalizaba y ocasionalmente incluso superaba el código escrito por los mejores expertos en ensamblaje en muchas áreas (aunque no siempre), y eso hizo que fuera obvio adoptar C para al menos la mayor parte de la codificación de un juego. Y un cambio similar ocurrió gradualmente en algún momento con C ++. La adopción de C ++ fue más lenta ya que creo que el aumento de la productividad de pasar de ensamblado a C probablemente podría llegar a un acuerdo unánime de los gamedevs que escriben juegos no triviales por completo en ASM en lugar de pasar de C a C ++.
Pero estos cambios no se debieron a que el hardware se volviera más poderoso, sino que los optimizadores para estos lenguajes hicieron que el nivel más bajo (aunque no siempre del todo, hay algunos casos oscuros) obsoleto.
Si puede imaginar un escenario hipotético en el que podríamos escribir código en el código de más alto nivel imaginable, sin preocuparse por subprocesos múltiples o GPU o errores de caché o algo por el estilo (tal vez ni siquiera estructuras de datos específicas), y el optimizador era como inteligencia artificial inteligente y podría descubrir los diseños de memoria más eficientes reorganizando y compactando nuestros datos, descubra que podría usar alguna GPU aquí y allá, paralelizar algún código aquí y allá, usar algo de SIMD, tal vez perfilarse y seguir optimizando su IR como humanos respondiendo a los puntos críticos del generador de perfiles, y lo hizo de una manera que supera a los mejores expertos del mundo, entonces sería una obviedad incluso para aquellos que trabajan en los campos más críticos de rendimiento adoptarlo ... y eso es un avance proveniente de optimizadores ridículamente inteligentes, no de hardware más rápido.