En general, sí. Pero no hay garantía, y los lugares donde el compilador lo hará son probablemente raros.
Lo que hacen la mayoría de los compiladores sin problemas es levantar las evaluaciones inmutables fuera de circuito, p. si su condición es
if (a<b) ....
cuando a y b no se ven afectados por el bucle, la comparación se realizará una vez antes del bucle.
Esto significa que si el compilador puede determinar que la condición no cambia, la prueba es barata y el salto se predijo. Esto a su vez significa que la prueba en sí cuesta un ciclo o ningún ciclo en absoluto (realmente).
¿En qué casos dividir el bucle sería beneficioso?
a) un lazo muy estrecho donde el 1 ciclo es un costo significativo
b) todo el circuito con las dos partes no se ajusta al código de caché
Ahora, el compilador sólo puede hacer suposiciones sobre el código caché y, por lo general, puede solicitar el código de forma que una rama se ajuste al caché.
Sin ninguna prueba, I'dexpect a) el único caso en el que se aplicaría tal optimización, robaba es nto siempre la mejor opción:
¿En qué casos dividir el bucle serían malos?
Al dividir el bucle aumenta el tamaño del código más allá de la memoria caché de código, recibirá un golpe significativo. Ahora, eso solo te afecta si el bucle se llama dentro de otro bucle, pero eso es algo que el compilador generalmente no puede determinar.
[editar]
no pude conseguir VC9 para dividir el siguiente bucle (uno de los pocos casos en los que en realidad podría ser beneficioso)
extern volatile int vflag = 0;
int foo(int count)
{
int sum = 0;
int flag = vflag;
for(int i=0; i<count; ++i)
{
if (flag)
sum += i;
else
sum -= i;
}
return sum;
}
[editar 2]
tenga en cuenta que con int flag = true;
la segunda rama se optimiza. (y no, const no hace una diferencia aquí;))
¿Qué significa eso? O no es compatible con eso, no importa, mi análisis es incorrecto ;-)
En general, supongo que es una optimización que es valiosa solo en unos pocos casos, y se puede hacer a mano fácilmente en la mayoría de los escenarios.
Gracias por la respuesta. Desde su enlace de wikipedia, encontré la página de "loopwitch", que parece ser un término aún más preciso para este tipo de optimización. –
Aunque los términos no son realmente cortados y secos, el levantamiento de bucles y el movimiento de código invariante de bucle no se usan realmente para describir esta optimización. Son más para instrucciones individuales. –
Enlace a 'loop unswitching' al que hace referencia OP: https://en.wikipedia.org/wiki/Loop_unswitching – BrodieG