por
pobrecito hablador
el Jueves, 13 Septiembre de 2007, 21:35h
(#959212)
No voy a discutir gran cosa porque está claro que te falta un hervor (o dos) pero como hoy no he hecho la buena acción del día quería aclararte al menos esto:
for (i=1; i!=100; i++) { } ¿Necesito un iterador? ¿Necesito un puntero?
No lo necesitas pero probablemente deberías usarlo. Normalmente los loops recorren arrays y el acceso es mucho más rápido por puntero que por índice. Si quieres hacer la prueba un test tonto puede ser (cambio tabulados por "-"):
int sum1(int *ptr, int len) {
----int r, *end;
----for(r = 0, end = ptr+len; ptr != end; ptr++)
--------r += *ptr;
----return r;
}
Frente a esto:
int sum2(int *ptr, int len) {
----int r, i;
----for (i = 0, r = 0; i < len; i++)
--------r += ptr[i];
----return r;
}
Escribe un mini test que gaste tiempo --pasando un puntero suficientemente grande o dando varias vueltas en un gran bucle--, compílalo con:
~$ gcc -O0 -pg -o test test.c
Y luego ejecuta y ve con gprof la diferencia. El -O0 es para evitar que gcc desenrolle bucles o que mapee el índice o el puntero en registros. Es para ver la velocidad lo menos adulterada posible. La razón de por qué sum1 es más rápido que sum2 se deja como ejercicio al lector. Pista: puedes ver el código ensamblado con "objdump -t test", busca sum1 y sum2 (si hay un call después de crear el marco de stack es porque el ejecutable lo compilaste para profiling, recompila o borra mentalmente)
Otras técnica para acelerar bucles es desenrollarlos tratando de alinear el código del loop con el tamaño de la cache pero hay que aprender a andar antes de correr:-) (además gcc con -O3 intenta hacerlo por ti)
... oh wait!..
¿Eres uno de los "expertos" de Menéame? Haber empezado por ahí, hombre de Dios:-)
Re:Pobre optimización
(Puntos:1, Informativo)int sum1(int *ptr, int len) {
----int r, *end;
----for(r = 0, end = ptr+len; ptr != end; ptr++)
--------r += *ptr;
----return r;
}
Frente a esto:
int sum2(int *ptr, int len) {
----int r, i;
----for (i = 0, r = 0; i < len; i++)
--------r += ptr[i];
----return r;
}
Escribe un mini test que gaste tiempo --pasando un puntero suficientemente grande o dando varias vueltas en un gran bucle--, compílalo con:
~$ gcc -O0 -pg -o test test.c
Y luego ejecuta y ve con gprof la diferencia. El -O0 es para evitar que gcc desenrolle bucles o que mapee el índice o el puntero en registros. Es para ver la velocidad lo menos adulterada posible. La razón de por qué sum1 es más rápido que sum2 se deja como ejercicio al lector. Pista: puedes ver el código ensamblado con "objdump -t test", busca sum1 y sum2 (si hay un call después de crear el marco de stack es porque el ejecutable lo compilaste para profiling, recompila o borra mentalmente)
Otras técnica para acelerar bucles es desenrollarlos tratando de alinear el código del loop con el tamaño de la cache pero hay que aprender a andar antes de correr