En el desarrollo de juegos hay mucho C / C ++, en las aplicaciones empresariales C #. He visto que los desarrolladores de C / C ++ expresan preocupación sobre cómo una sola línea de código se traduce en ensamblaje. En .NET algunos entran en IL, raramente.
En C #, la "micro-optimización" está mal vista, es raro y generalmente es una pérdida de tiempo. Este no parece ser el caso en el desarrollo de juegos.
¿Qué crea específicamente esta inconsistencia? ¿Los juegos superan constantemente los límites del hardware? 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?
No estoy buscando un debate sobre la viabilidad de C # como desarrollador de juegos. Sé que se ha hecho hasta cierto punto. Centrarse en la microoptimización. Específicamente, la diferencia entre Game Dev vs Aplicaciones dev.
ACTUALIZACIÓN
Por juego me refiero al desarrollo moderno a gran escala. Por ejemplo, MMORPG, Xbox, PS3, Wii ...
fuente
Respuestas:
En las aplicaciones empresariales, la CPU no siempre es el cuello de botella. Una aplicación comercial pasaría la mayor parte del tiempo esperando. P.ej:
Es por eso que el código que optimiza el rendimiento del procesamiento no agrega demasiado valor.
La consideración principal es:
fuente
En aplicaciones comerciales, es muy raro que importen los microsegundos. En los juegos, es un hecho de la vida.
Si desea que un juego se ejecute a 60 cuadros por segundo, tiene ~ 16.67 milisegundos para hacer todo lo que se necesita hacer para ese cuadro: entrada, física, lógica de juego, audio, redes, IA, renderizado, etc. Si tiene suerte, correrá a 30 fps y tendrá 33.3 milisegundos de lujo. Si un marco lleva demasiado tiempo, sus comentarios se verán afectados, sus jugadores llenarán los foros de Internet con bilis y no venderá tanto como podría (sin mencionar el golpe a su orgullo profesional) y si realmente tiene mala suerte encontrará a su equipo codificando aplicaciones comerciales para ganarse la vida.
Por supuesto, los desarrolladores de juegos no se preocupan por cada línea, ya que, con experiencia y un perfilador decente, usted aprende qué líneas deben preocuparse. Por otro lado, esas preocupaciones a veces tocarán cosas que en el mundo empresarial probablemente se considerarían nanooptimizaciones en lugar de microoptimizaciones.
No espere que ningún lenguaje de alto nivel expulse a C ++ hasta que uno ofrezca un rendimiento comparable y predecible.
fuente
Bien, entonces has visto desarrolladores de C y C ++ obsesionados con líneas individuales. Apuesto a que no se obsesionan con cada línea.
Hay casos en los que desea el máximo rendimiento, y esto incluye muchos juegos. Los juegos siempre han tratado de superar los límites de rendimiento para verse mejor que su competencia en el mismo hardware. Esto significa que aplica todas las técnicas habituales de optimización. Comience con algoritmos y estructuras de datos, y avance desde allí. Al usar un generador de perfiles, es posible encontrar dónde se está tomando la mayor parte del tiempo y dónde es posible obtener ganancias significativas de la micro-optimización de unas pocas líneas.
Esto no se debe a que los idiomas obligan a las personas a hacerlo, es que las personas eligen los idiomas en función de lo que quieren hacer. Si desea extraer el último rendimiento de un programa, no escribirá C # y compilará en el CLR y esperará que el compilador JIT (o lo que sea) haga un buen trabajo, escríbalo en algo donde pueda controlar en gran medida La salida. Utilizará C o C ++ (y probablemente un subconjunto restringido de C ++) y estudiará la salida en lenguaje ensamblador y los resultados del generador de perfiles.
Hay muchas personas que usan C y C ++ y no se preocupan demasiado por los detalles de la traducción, siempre que parezca lo suficientemente rápido.
fuente
¿Los juegos superan constantemente los límites del hardware?
Ellos si.
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?
En realidad no, porque a medida que el hardware mejora, los consumidores esperan que los juegos también mejoren. No esperan ver la misma calidad de juego desarrollada de manera más eficiente porque los desarrolladores usaron un lenguaje de nivel superior. Esperan que se les vuelen los calcetines con cada nueva plataforma.
Por supuesto, hay algo de movimiento. Cuando era un muchacho y me interesé por primera vez en el desarrollo de juegos, era un montaje escrito a mano, o largarme. Esta fue la era del Commodore 64. Hoy en día, por supuesto, C ++ es la lengua franca de la mayoría de los desarrollos de juegos. Y, de hecho, incluso hemos visto un movimiento hacia el uso de C ++ para el código del motor y un lenguaje de secuencias de comandos de nivel superior para el código lógico del juego. por ejemplo, LUA, o el motor Unreal tiene su propio lenguaje UnrealScript.
fuente
Si solo puede ensamblar su aplicación con código de alto nivel y código de biblioteca, seguro que es una pérdida de tiempo. Escríbalo en un idioma interpretado si lo desea en ese caso; No hará mucha diferencia. Si está tratando de implementar un motor de iluminación global de vanguardia que voxeliza el contenido dinámico de la escena sobre la marcha en tiempo real como lo hizo CryEngine 3 , naturalmente no puede librarse de la necesidad de micro-optimizar.
fuente
"Juego" es un término bastante amplio. Si tuviera, digamos, un MMORPG, las optimizaciones más pequeñas afectarían a muchos jugadores.
Los jugadores están, y probablemente siempre han estado, acostumbrados a una cantidad relativamente grande de cosas que suceden a la vez, en tiempo real. Seguro; en un momento, tener un Pacman o Tetris receptivo era el objetivo. Pero aún tenían que ser receptivos. Hoy en día, 3DMMORPGs a través de conexiones de red de caída de paquetes.
Seguro entiendo el deseo de optimizar.
fuente
Los juegos realizan constantemente grandes cantidades de procesamiento en segundo plano. Las aplicaciones comerciales no lo hacen.
fuente
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.
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 escribir
if/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:
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.
fuente
Tienes un problema de terminología aquí. Estás usando las palabras correctamente, pero los desarrolladores de juegos y la gente de negocios están usando el mismo término de dos maneras muy diferentes.
Para las empresas, la "micro optimización" significa acelerar un paso muy pequeño en el proceso empresarial general implementado por el software. La razón por la que está mal visto es típicamente una de:
El desarrollo del juego es una bestia diferente. La "micro optimización" está ahorrando una pequeña cantidad de tiempo en una función o rutina.
Entonces, en los negocios, a nadie le importa si la forma de un proceso comercial de 4 pasos se presenta en 0.6 segundos o 0.5 segundos. En los juegos, a uno le importa si una rutina que dura 200 ms se puede reducir a la ejecución en 100 ms.
Se trata del valor entregado al cliente, las necesidades del cliente y la relación costo-beneficio del cambio.
fuente
Tiene que ver con por qué esa herramienta fue seleccionada para un trabajo en particular.
Los golfistas se obsesionan con la dirección y la fuerza que aplican con un putter, no tanto cuando usan el controlador.
¿Por qué? Porque son diferentes tipos de disparos. Para conducir, desea obtenerlo en la calle con la máxima distancia. Para un putt, quieres meterlo exactamente en el hoyo.
Lo mismo se aplica aquí. Los desarrolladores de juegos eligen C ++ porque les da control sobre el rendimiento de diferentes operaciones. Si ha elegido eso, querrá aprovecharlo.
fuente
La mayoría de las aplicaciones comerciales se escriben como herramientas internas. Las expectativas sobre la usabilidad de estas herramientas son mucho más bajas que en el caso del software vendido a clientes masivos. Es bastante común que una aplicación comercial interna tenga menús y cuadros de diálogo que reaccionan lentamente a los clics del mouse, ventanas que se vuelven a dibujar con retraso o incluso una GUI escrita en Swing (¡el horror!). Esto se debe a una serie de razones (es más importante que el software sea personalizable que muy "ágil", los usuarios del software no tienen opción de usar o no el software en cuestión, las personas que hacen decisión de instalar el software no lo utilicen ellos mismos ...). La consecuencia de todo esto es que los desarrolladores de estas herramientas no pasan mucho tiempo optimizando la capacidad de respuesta de la aplicación, pero se preocupa mucho por la extensibilidad y la cantidad de características. Base de clientes diferente => objetivos de diseño diferentes => metodología diferente.
Tenga en cuenta que una aplicación empresarial dirigida a un público masivo, como Excel, está muy optimizada.
fuente