Solía escribir mucho ensamblador en el día. No es solo que los compiladores hayan mejorado, sino que la mayoría del hardware ahora tiene mucha lógica dedicada a la ejecución de código fuera de orden. El verdadero micro problema es la programación, la mayoría de las instrucciones de la computadora toman varios relojes de máquina para producir un resultado, ¡y una carga de memoria que pierde memoria caché puede tomar varios cientos! Entonces, la idea era programar otras instrucciones para hacer algo útil, en lugar de esperar un resultado. Y las máquinas modernas pueden emitir varias instrucciones por período de reloj. Una vez que comenzamos a ejecutar HW fuera de orden, descubrí que tratar de obtener un gran rendimiento con la codificación manual se convirtió en un juego de tazas. Primero, el HW fuera de orden no ejecutará las instrucciones en su orden cuidadosamente elaborada, La nueva y elegante arquitectura HW ha reducido la penalización de la programación de software inóptima lo suficiente como para que el compilador generalmente esté dentro de un pequeño porcentaje de su rendimiento. También descubrí que los compiladores ahora estaban implementando trucos conocidos pero generadores de complejidad, como desenrollar, cargar el fondo, canalizar el software, etc. La conclusión es que tienes que trabajar muy duro, omite algunos de estos trucos y el compilador te gana. ¡Utilícelos todos y la cantidad de instrucciones de ensamblador que necesita aumentará varias veces!
Probablemente aún más importante, la mayoría de los problemas de rendimiento, no se trata de tasas de problemas de instrucción, sino de introducir los datos en la CPU. Como mencioné anteriormente, la latencia de la memoria ahora es de cientos de ciclos, y la CPU puede ejecutar varias instrucciones por período de reloj, por lo tanto, a menos que el programa, y especialmente las estructuras de datos, estén diseñadas para que la tasa de aciertos de la caché sea extremadamente alta, la microtuning en la instrucción nivel no tendrá resultado. Al igual que los tipos militares dicen que los aficionados hablan de tácticas, los profesionales hablan de logística. La programación de rendimiento ahora es más del 90% de logística (datos móviles). Y esto es difícil de cuantificar, ya que la administración de memoria moderna generalmente tiene múltiples niveles de caché, y las páginas de memoria virtual son manejadas por una unidad de hardware llamada TLB. También la alineación de bajo nivel de las direcciones se vuelve importante, ya que las transferencias de datos reales no están en unidades de bytes, o incluso de 64 bits de largo, pero vienen en unidades de líneas de caché. Entonces, la mayoría de las máquinas modernas tienen hardware que intenta predecir qué línea de caché se pierde en un futuro cercano y emiten prefetches automáticos para llevarlos al caché. Entonces, la realidad es que con las CPU modernas, los modelos de rendimiento son tan complejos que son casi incomprensibles. Incluso los simuladores de hardware detallados nunca pueden coincidir con la lógica exacta de los chips, por lo que el ajuste exacto es simplemente imposible.
Todavía hay un lugar para algunas codificaciones manuales. Las bibliotecas matemáticas (como la función exp), al igual que las operaciones de álgebra lineal más importantes (como la multiplicación de matrices) todavía suelen estar codificadas manualmente por expertos que trabajan para el proveedor de hardware (es decir, Intel o AMD o IBM), pero probablemente solo necesita un par de programadores de ensamblador de primer nivel por cada megacomputadora.