En la superficie todos sabemos que los mejores procesadores son aquellos que pueden hacer más con menos, desarrollando la mayor velocidad posible sin disparar su consumo energético, pero una vez que cruzamos la barrera de las especificaciones básicas descubrimos que los procesadores modernos en general buscan pre-calcular, anticipar y predecir todo lo que pasa por ellos. El youtuber Matt Godbolt describe esto a través de cinco aspectos muy poco conocidos por el usuario promedio, y que a pesar de su complejidad técnica, no dejan de ser fascinantes.
Una de las primeras cosas que cualquier persona recuerda de los primeros procesadores Atom es que eran lentos como caracoles. En esencia, lo que hizo Intel fue priorizar el bajo consumo sobre el rendimiento, aplicando una nueva arquitectura basada en conceptos antiguos, y una de las cosas que quedó en el tintero fue la ejecución out-of-order.
¿De qué se trata? En términos relajados, es uno de los tantos trucos que los procesadores actuales tienen a su disposición para acelerar la ejecución de instrucciones. Cualquiera que trate de entender mejor a esos trucos deberá sumergirse en el extraño mundo de las arquitecturas, y en especial las desarrolladas por Intel. La alternativa es ver este vídeo publicado por Matt Godbolt, que describe a cinco de ellos:
Cinco cosas que hace un CPU
- Tratan de adivinar cómo se accede a tus datos y reconocer patrones, una forma de prefetching que se traduce en un importante aumento de la velocidad. Dicho de otro modo, cargan líneas de caché automáticamente antes de que las necesites, quedando un paso por delante del proceso.
- Convierten CISC («Complex» Instruction Set Computing) en RISC («Reduced» Instruction Set Computing). Las operaciones de la primera arquitectura son transformadas en una serie de «microcódigo» o «micro-operaciones» que pueden ser programadas de forma independiente, ganando simplicidad y eficiencia.
- Reorganizan la ejecución de código. El orden en el que se escribe el código no es el orden en el que es ejecutado por los procesadores. La independencia entre bloques permite ejecutar instrucciones aún mientras otro grupo se encuentra en espera.
- Convierten el código a SSA. Explicar SSA de manera sencilla es un desafío enorme, pero Godbolt lo reduce a una serie de optimizaciones que verifican si el código es en verdad independiente (algo esencial para las acciones previas), y en caso de no serlo, reescribirlo para que adquiera esa propiedad. En su ejemplo utiliza registros «ficticios» como EAX1 y EAX2.
- Predicen el futuro. Aquí es cuando interviene el llamado predictor de saltos, que como sugiere su nombre tiene la tarea de anticipar si un salto condicional se producirá o no, clasificando de especulativos a los resultados. Si la predicción falla, se descartan. Si acertó, ya están cargados. Más velocidad.
En resumen: Precarga de datos, conversión a microcódigo, ejecución out-of-order, renombre de registros, y predicción de saltos. Si algo de todo esto te recuerda a esos niños malos llamados Spectre y Meltdown, es porque en cierto modo surgen de debilidades en estas tareas. La relación entre velocidad y seguridad requiere un equilibrio mucho más delicado de lo que imaginamos…