Aprendiendo a optimizar con Ensamblaje [cerrado]

21

Soy estudiante de segundo año de tecnología de juegos de computadora Recientemente terminé mi primer prototipo de mi "tipo" de pathfinder propio (que no utiliza A * en lugar de un enfoque geométrico / reconocimiento de patrones, el pathfinder solo necesita el conocimiento sobre el terreno que está en su opinión para tomar decisiones, porque yo quería una IA que realmente pudiera explorar, si el terreno ya se conoce, entonces caminará fácilmente por el camino más corto, porque el buscador de caminos tiene memoria de nodos).

De todos modos, mi pregunta es más general: ¿Cómo empiezo a optimizar algoritmos / bucles / for_each / etc. usando el ensamblaje, aunque los consejos generales son bienvenidos. Estoy buscando específicamente buenos libros, porque es realmente difícil encontrar buenos libros sobre este tema. Hay algunos artículos pequeños como este , pero aún no hay suficiente conocimiento para optimizar un algoritmo / juego ...

Espero que haya un buen libro moderno por ahí, que simplemente no pude encontrar ...

Niktehpui
fuente
1
Esto no responde a su pregunta directamente, pero se ha investigado A * exploratorio (llamado adaptativo) y tiene un rendimiento realmente bueno (lo que significa que no necesitará optimizarlo usando ASM). Echa un vistazo a D * Lite .
Jonathan Dickinson el

Respuestas:

21

Voy a ser el que vaya contra la corriente aquí y decir, nunca es demasiado temprano para aprender sobre optimizaciones, especialmente optimizaciones de ensamblaje y, lo que es más importante, depuración en ensamblaje. Creo que obtendrás el máximo beneficio si eres un estudiante (porque entonces tienes muy poco que perder [es decir, en cuanto al tiempo / dinero]) y mucho que ganar.

Si está en la industria y no tiene la tarea de retocar en el ensamblaje, entonces no lo haga. De lo contrario, si eres estudiante o tienes tiempo en general, encontraría el tiempo para aprender a desmontar programas y ver si puedo encontrar una solución mejor que el compilador. Si no puedo, a quién le importa! Acabo de aprender a escribir, así como al compilador y eso es una GRAN ventaja cuando te enfrentas a un error en el código de lanzamiento (sin símbolos de depuración) y miras el desmontaje porque eso es lo único que puedes ver.

La respuesta

Este es uno de los mejores recursos que he encontrado para aprender sobre optimizaciones.

http://www.agner.org/optimize/

El despotricar

Si lee algunos artículos de los principales desarrolladores (por ejemplo, el razonamiento detrás de la creación de EASTL y una inspección más cercana del código lo llevará a comentarios como este porque GCC es terrible al incluir esta declaración if que le dirá, lo que la mayoría de la gente dice que confías en que el compilador no siempre es correcto, ESPECIALMENTE en el desarrollo de juegos) y luego pones un pie en la industria, encontrarás que las optimizaciones son algo cotidiano y saber lo que significa la salida del ensamblaje es una gran ventaja. Además, las personas no parecen darse cuenta (especialmente en stackoverflow) de que la creación de perfiles de juegos es muy difícil y no siempre precisa.

Sin embargo, hay una advertencia. Puedes pasar tiempo optimizando algo y luego darte cuenta de que fue una pérdida de tiempo. Pero que aprendiste? Aprendiste a no repetir ese mismo error en una circunstancia similar.

Lo que SO está tomando ahora es, en mi opinión, una postura religiosa a la declaración que no se optimiza hasta su perfil y no se preocupe, el compilador sabe mejor que usted . Se dificulta el aprendizaje. Conozco a expertos en la industria a quienes se les paga muy buen dinero (y quiero decir, MUY buen dinero) para jugar en el ensamblaje para optimizar el juego y depurarlo porque el compilador es malo o simplemente no puede ayudarte, porque, bueno, no puede (fallas relacionadas con GPU, fallas donde los datos involucrados son imposibles de leer en un depurador, etc., etc.)

¡Qué pasa si alguien a quien le encanta hacer eso, aún no se ha dado cuenta completamente, hace la pregunta aquí y es rechazado / apagado por las muchas respuestas que el compilador conoce mejor que usted! y nunca se convierte en uno de esos programadores altamente pagados?

Un pensamiento final. Si comienza a hacer esto temprano, descubrirá que pronto comenzará a escribir código que es peor, no tiene mejoras de rendimiento porque el compilador lo optimizó de la misma manera o, en el mejor de los casos, tiene algunas mejoras de rendimiento porque ahora el compilador puede optimizarlo . En cualquier caso, se ha convertido en un hábito, y no es más lento para escribir código de esta manera que antes. Un par de ejemplos son (hay muchos más):

  1. Incremento previo a menos que realmente desee un incremento posterior
  2. Escribir bucles para contenedores utilizando una variable de tamaño local constante en lugar de llamar a size () en el contenedor dentro del bucle.

EDITAR: Actualización después de 8 años más en la industria. Aprender montaje. Aprenda cómo funcionan los optimizadores y el ensamblaje que generan (CompilerExplorer es una gran herramienta para eso). Me he encontrado con innumerables bloqueos en las compilaciones de prueba (compilaciones optimizadas para pruebas internas) en las que no puede confiar en el depurador incluso con símbolos de depuración. El compilador ha optimizado demasiadas cosas y el ensamblaje es su única fuente de información valiosa para encontrar el error del volcado de memoria. Cada construcción demora entre 30 y 40 minutos si tiene suerte y es el primero en la cola de construcción, por lo que no puede confiar en algunas técnicas tradicionales para aislar el error. El modo multijugador empeora las cosas. Conocer el ensamblaje y cómo leer el ensamblaje optimizado simplemente lo hará mejor y, en última instancia, más valioso para el equipo.

Samaursa
fuente
1
Buen punto sobre la optimización de compiladores. Son geniales para tener, pero están lejos de ser perfectos, y a diferencia de lo que algunas personas creen, generalmente no es difícil encontrar una optimización simple que un compilador no hizo.
aaaaaaaaaaaa
3
Cabe señalar que existe una diferencia entre "aprender a leer el ensamblaje" y "aprender a optimizar con el ensamblaje". Los dos no son lo mismo, y su respuesta realmente no toca el uso del ensamblaje para implementar optimizaciones. Leer el ensamblaje es una habilidad útil, ya que puede ayudar a depurar y detectar lugares donde el compilador no está haciendo algo bien. Pero eso es muy diferente de usar el ensamblaje para escribir rutinas optimizadas, lo que requiere un profundo conocimiento de la programación de instrucciones para una CPU específica. Y también es algo que no cubriste.
Nicol Bolas
1
Además, "Acabo de aprender a escribir y compilar" No, no lo hiciste. Viste cómo se compiló una rutina específica para una CPU específica. Aprender a implementar rutinas de ensamblaje optimizadas requiere más que simplemente observar cómo el compilador compiló una rutina. Debe comprender por qué el compilador eligió esos códigos de operación en ese orden para reproducir ese código específico de C ++. Y eso requiere un conocimiento profundo de la CPU, la programación de instrucciones, etc. Generalizar esto requiere años de experiencia; no lo obtendrá simplemente decodificando un par de rutinas.
Nicol Bolas
77
Entonces, -1 para A: en realidad no responde la pregunta sobre cómo escribir rutinas optimizadas para ensamblaje. B: tergiversar lo fácil que es aprender a vencer al compilador al escribir rutinas optimizadas para ensamblar. Y C: alentar a un programador a mirar las optimizaciones a nivel de ensamblaje antes que las optimizaciones a nivel de algoritmo. Incluso esos "expertos en la industria" altamente remunerados le dirían que eso está poniendo el carro delante del caballo.
Nicol Bolas
2
@Samaursa: Nadie dijo que la gente no debería "entender el desmontaje y cómo optimizar el código". Este no es un debate religioso; Es una cuestión de simple hecho. La gente ha dedicado siglos a la optimización manual de algunas rutinas solo para descubrir que no significa nada para el rendimiento general. Aprender a optimizar algoritmos es un conjunto de habilidades de gran valor. Aprender a leer el ensamblaje es un conjunto de habilidades semi-valiosas. Aprender a escribir rutinas de ensamblaje es un conjunto de habilidades que rara vez se usa. Y en estos días, las mejores optimizaciones provienen de una mejor utilización de la caché, no del ensamblaje manual.
Nicol Bolas
22

El primer consejo que obtendrás es este: no lo hagas.

Los compiladores modernos son realmente muy buenos para optimizar el código, y es mucho más probable que lo hagan mejor que cualquier lenguaje de ensamblaje automático que pueda escribir.

La excepción sería cualquier caso específico en el que haya determinado con certeza que el compilador está haciendo un mal trabajo de optimización, así que ese es el segundo consejo. No hay pautas generales aquí, debe conocer su propio código, saber lo que está haciendo, ser capaz de saltar al desarmado y ser capaz de determinar con certeza absoluta que el compilador está haciendo un mal trabajo.

Incluso en este caso, es posible que aún no quieras. Debe asegurarse de que no habrá gastos generales de mantenimiento continuos para usted. Es posible que desee volver a este código dentro de 6 meses y modificar parte de él, o puede encontrar un error extremadamente sutil que será más difícil de solucionar en una versión en lenguaje ensamblador. Incluso si cree que ha solucionado todos los errores, una vez que su programa pasa a los errores públicos que nunca pensó que podría suceder, se convertirá en una realidad para usted. Eso es bastante revelador (y una experiencia humillante).

E incluso si está contento de aceptar eso, aún puede encontrar que no hay absolutamente ninguna mejora medible en el rendimiento ya que su cuello de botella principal podría estar en algún lugar completamente diferente en su programa. Entonces eso me lleva nuevamente al número 1. No lo hagas

Maximus Minimus
fuente
15

Por lo general, la optimización sólida no depende del uso de Assembly o de realizar microoptimizaciones con código en lenguajes de nivel superior. Si lee una gran cantidad de trabajos de investigación (¡como yo lo hago, o lo intento!), Verá que a menudo las mejoras realizadas a los algoritmos están en un nivel conceptual más amplio, "cualitativo", en lugar de en un nivel más "cuantitativo" nivel de microoptimización. Destacaría que es más probable que se encuentren ganancias de orden de magnitud al observar los algoritmos desde este punto de vista, o al vectorizar / paralelizar las soluciones existentes.

Dicho esto, recientemente me encontré con esto , que puede ser una buena ruta para aprender x86 ASM específicamente para desarrolladores de juegos.


APÉNDICE

Dos fuentes de la parte superior de mi cabeza:

Además, leer trabajos de investigación es una excelente manera de seguir los procesos de pensamiento de los sabios, ya que optimizan los algoritmos para un mejor rendimiento. Muy a menudo, las ganancias se ven por:

  • Reducir el uso de las operaciones más costosas (div, SQRT, trig ops y condicionales, principalmente);
  • Mejora del rendimiento de la caché mediante el uso de estructuras de datos más eficientes, alineación de memoria y condicionales reducidos;
  • Reducción de la calidad de salida en áreas aceptables para mejorar el rendimiento;
  • Vectorización (SIMD);
  • Paralelismo (subprocesamiento, incluye el cambio de tareas a la GPU);
  • Y, por supuesto (cada vez más raramente) ensamblado codificado a mano. Primero inspeccione los ensamblados C / C ++ para ver dónde el compilador está haciendo elecciones no óptimas, por supuesto. Encontrará más de esto en documentos anteriores de los años 80 y 90, IME.

La investigación de lectura también lo mantiene a la vanguardia de su campo, en lugar de esperar que ese conocimiento se filtre en la industria.

Ingeniero
fuente
usted habla sobre la optimización de algoritmos pero no proporciona información al respecto, si tuviéramos que seguir sus consejos y analizarlos, ¿podría darnos alguna dirección?
Skeith
De hecho, lo menciono; necesita estudiar algoritmos, entendiendo qué es lo que hacen los informáticos para mejorar cualitativamente el rendimiento. Sumérgete en esto lo suficiente, y con el tiempo, comenzarás a pensar en términos similares. Los esfuerzos incrementales aquí dan buenos resultados, en lugar de pasar años (y recientemente vi esto mencionado en un foro ASM) dominando los entresijos de (solo), por ejemplo. Arquitectura x86. Caza el gran juego: aprende a reducir los problemas hasta su núcleo y luego decide qué es superfluo para optimizarlo. Ver libros de referencia arriba.
Ingeniero
@NickWiggill ¿Cuál es su fuente habitual de trabajos de investigación?
kizzx2
3

Creo que puede ser muy temprano.

De todos modos, es importante entender que el compilador en sí no produce un código más lento que el equivalente de ensamblado, no obtiene ningún rendimiento simplemente escribiendo el mismo código de ensamblaje que el compilador.

Para empezar, al menos concéntrese en optimizaciones sin ensamblaje. Igor Ostrovsky tiene algunos buenos artículos que demuestran algunos de los conceptos básicos: http://igoro.com/archive/fast-and-slow-if-statements-branch-prediction-in-modern-processors/

Tenga en cuenta que las predicciones erróneas de rama y las fallas de caché son contra lo que debe optimizar principalmente, incluso si tiene que pagar haciendo algunas operaciones aritméticas adicionales, generalmente vale la pena evitar una rama impredecible o leer al azar de demasiada memoria.

Y, por supuesto, lo más importante, optimice su algoritmo primero. Una implementación lenta de un algoritmo rápido casi siempre será más rápida que una implementación rápida de un algoritmo lento.

aaaaaaaaaaaa
fuente
2

Este libro es excepcionalmente bueno para un libro de texto. Pero no está específicamente orientado a la optimización. Lenguaje ensamblador para procesadores x86, sexta edición

Se trata más de enseñar los fundamentos del ensamblaje, utilizando MASM. Luego, hacia el final del libro, aborda cómo ensamblar en línea con c ++ e integrarlo en programas más grandes.

Puse esto aquí porque tiene sentido aprender los fundamentos del ensamblaje antes de aprender cómo optimizar programas con él.

Me gusta este libro porque Irvine te enseña cómo usar las herramientas necesarias para escribir programas masm. Específicamente entra en cómo usar el IDE (Visual Studio C ++) y el depurador. Cada capítulo tiene algunos videos dedicados a resolver problemas. Parte de esta información está disponible gratuitamente en el sitio web que se detalla.

NadtheVlad
fuente
1
"tiene sentido aprender los fundamentos del ensamblaje antes de aprender cómo optimizar los programas con él" - buenos consejos.
Maximus Minimus