Donde he trabajado, siempre usamos múltiples niveles de creación de perfiles; Si ve un problema, simplemente baje un poco más en la lista hasta que descubra lo que está sucediendo:
- El "perfilador humano", también conocido como solo jugar el juego ; ¿Se siente lento o "enganche" ocasionalmente? ¿Te das cuenta de animaciones desiguales? (Como desarrollador, tenga en cuenta que será más sensible a algunos tipos de problemas de rendimiento y ajeno a otros. Planifique las pruebas adicionales en consecuencia).
- Encienda la pantalla FPS , que es un FPS promedio de 5 segundos con ventana deslizante. Muy poca sobrecarga para calcular y mostrar.
- Active las barras de perfil , que son solo una serie de quads (colores ROYGBIV) que representan diferentes partes del marco (por ejemplo, vblank, preframe, update, collision, render, postframe) usando un temporizador simple "cronómetro" alrededor de cada sección de código . Para enfatizar lo que queremos, configuramos un ancho de pantalla equivalente a un marco objetivo de 60Hz, por lo que es realmente fácil ver si está, por ejemplo, un 50% por debajo del presupuesto (solo media barra) o un 50% por encima ( la barra se enrolla y se convierte en una barra y media). También es bastante fácil saber qué es lo que generalmente consume la mayor parte del marco: rojo = renderizado, amarillo = actualización, etc.
- Cree una compilación instrumentada especial que inserte "cronómetro" como código alrededor de todas y cada una de las funciones. (Tenga en cuenta que puede obtener un rendimiento masivo, dcache e icache al hacer esto, por lo que definitivamente es intrusivo. Pero si carece de un perfil de muestreo adecuado o un soporte decente en la CPU, esta es una opción aceptable. También puede ser inteligente sobre el registro de un mínimo de datos sobre la función enter / exit y la reconstrucción de calltraces más tarde). Cuando creamos el nuestro, imitamos gran parte del formato de salida de gprof .
- Lo mejor de todo, ejecute un generador de perfiles de muestreo ; VTune y CodeAnalyst están disponibles para x86 y x64, tiene varios entornos de simulación o emulación que pueden proporcionarle datos aquí.
(Hay una historia divertida del GDC del año pasado de un programador de gráficos que tomó cuatro fotos de sí mismo: feliz, indiferente, molesto y enojado, y mostró una imagen apropiada en la esquina de las construcciones internas en función de la velocidad de fotogramas. los creadores de contenido aprendieron rápidamente a no activar sombreadores complicados para todos sus objetos y entornos: harían enojar al programador. Contemplen el poder de la retroalimentación).
Tenga en cuenta que también puede hacer cosas divertidas como graficar las "barras de perfil" continuamente, para que pueda ver patrones de espiga ("estamos perdiendo un cuadro cada 7 cuadros") o similares.
Para responder a su pregunta directamente, sin embargo: en mi experiencia, mientras que es tentador (y, a menudo recompensar - Por lo general aprendo algo) para volver a escribir funciones / módulos individuales al número Optimizar de instrucciones o Icaché o dcache rendimiento, y lo hacemos realmente necesita hacer esto a veces cuando tenemos un problema de rendimiento particularmente desagradable, la gran mayoría de los problemas de rendimiento que tratamos regularmente se reducen al diseño . Por ejemplo:
- ¿Deberíamos almacenar en caché en RAM o recargar desde el disco los cuadros de animación de estado de "ataque" para el jugador? ¿Qué tal para cada enemigo? No tenemos RAM para hacerlos todos, ¡pero las cargas de disco son caras! ¡Puedes ver el enganche si aparecen 5 o 6 enemigos diferentes a la vez! (Bien, ¿qué tal escalonar el desove?)
- ¿Estamos haciendo un solo tipo de operación en todas las partículas, o todas las operaciones en una sola partícula? (Esta es una compensación icache / dcache, y la respuesta no siempre es clara). ¿Qué tal si separamos todas las partículas y almacenamos las posiciones juntas (la famosa "estructura de matrices") versus mantener todos los datos de partículas en un solo lugar (" matriz de estructuras ").
Lo escuchas hasta que se vuelve desagradable en cualquier curso de informática de nivel universitario, pero: realmente se trata de estructuras de datos y algoritmos. Dedicar algo de tiempo al algoritmo y al diseño del flujo de datos le dará más beneficios en general. (Asegúrese de haber leído las excelentes diapositivas de las diapositivas de la programación orientada a objetos de un compañero de Sony Developer Services para obtener una idea aquí). Esto no "se siente" como una optimización; es principalmente el tiempo que se pasa con una pizarra o herramienta UML o creando muchos prototipos, en lugar de hacer que el código actual se ejecute más rápido. Pero generalmente vale mucho más la pena.
Y otra heurística útil: si está cerca del "núcleo" de su motor, puede valer la pena un esfuerzo extra y experimentación para optimizar (por ejemplo, ¡vectorice esas multiplicaciones matriciales!). Cuanto más lejos del núcleo, menos debería preocuparse por eso a menos que una de sus herramientas de creación de perfiles le indique lo contrario.