Reservar registros en GCC: cómo la escasez forzada dispara los spills y ralentiza el código

Fuentes: Register deprivation: spills and runtime under forced register scarcity

Un experimento con nueve kernels pequeños compilados con GCC 15.2.0 en un Intel Xeon E-2236 mide qué ocurre cuando se obliga al compilador a trabajar con cada vez menos registros, usando el flag -ffixed-. De los nueve núcleos probados, ocho se ralentizan entre un 14% y un 76% al llegar al presupuesto más ajustado; el noveno, SipHash-2-4, no se mueve. En todos los casos los resultados numéricos son idénticos, lo que confirma que la reserva de registros solo cambia el código generado, no la computación.

El trabajo pone a prueba tres hipótesis: que quitar registros aumenta los spills y el tiempo de ejecución, que el efecto depende del fichero de registros que el kernel usa realmente, y que el número estático de spills predice el coste en runtime. La primera se cumple en dirección pero no de forma monótona; la segunda se cumple, aunque con matices, porque GCC auto-vectoriza partes de SHA-256 con SSE a -O2, de modo que reservar XMM no es inocuo para un kernel entero; la tercera, en cambio, falla: la correlación de Pearson entre spills añadidos y ralentización es solo 0,55 sobre 105 puntos.

El coste por spill varía hasta treinta veces entre kernels: el filtro FIR paga alrededor de 2,18% por cada spill añadido, mientras que LZ77 paga apenas un 0,25% y SipHash cerca de cero. Los autores lo atribuyen a que los spills que caen fuera del camino crítico se atienden desde la caché L1 de forma casi gratuita, mientras que los que interrumpen una recurrencia estrecha serializan el pipeline. Los datos completos están disponibles en el repositorio spillbench y en results.json.