En informática , la inversión de bucle es una optimización del compilador y una transformación de bucle en la que un bucle while se reemplaza por un bloque if que contiene un bucle do..while . Cuando se utiliza correctamente, puede mejorar el rendimiento debido a la segmentación de instrucciones .
int i , a [ 100 ]; i = 0 ; mientras ( i < 100 ) { a [ i ] = 0 ; i ++ ; }
es equivalente a:
int i , a [ 100 ]; i = 0 ; si ( i < 100 ) { hacer { a [ i ] = 0 ; i ++ ; } mientras ( i < 100 ); }
A pesar de la aparente mayor complejidad del segundo ejemplo, en realidad puede ejecutarse más rápido en las CPU modernas porque utilizan una secuencia de instrucciones . Por naturaleza, cualquier salto en el código provoca un bloqueo de la secuencia de instrucciones , lo que perjudica el rendimiento.
Además, la inversión de bucle permite un movimiento de código seguro e invariante al bucle .
yo := 0 L1: si i >= 100 pasamos a L2 a[i] := 0 yo := yo + 1 ir a L1 Nivel 2:
Si se hubiera inicializado en 100, las instrucciones ejecutadas en tiempo de ejecución habrían sido:
si i >= 100 Ir a L2
Supongamos que i se ha inicializado con un valor inferior a 100. Ahora veamos las instrucciones que se ejecutan en el momento en que i se ha incrementado a 99 en el bucle:
ir a L1 si yo < 100 a[i] := 0 yo := yo + 1 ir a L1 si i >= 100 Ir a L2 <<en L2>>
Ahora veamos la versión optimizada:
yo := 0 si i >= 100 voy a L2 L1: a[i] := 0 yo := yo + 1 Si i < 100 voy a L1 Nivel 2:
Nuevamente, veamos las instrucciones que se ejecutan si i se inicializa a 100:
si i >= 100 Ir a L2
No hemos desperdiciado ningún ciclo en comparación con la versión original. Ahora, consideremos el caso en el que i se ha incrementado a 99:
si yo < 100 ir a L1 a[i] := 0 yo := yo + 1 si yo < 100 <<en L2>>
Como puede ver, se han eliminado dos goto (y, por lo tanto, dos bloqueos de canalización) en la ejecución.