For hasta 6.000.000.000 en C
Publicado el Viernes, 25 de abril de 2008Una de las cosas que más disfruto del blog, es cuando se genera un intercambio con los lectores. Y algo que realmente aprecio, es ser corregido (cuando tienen razón, ¿no? sino simplemente molesta...). Hay gente que se toma esto a mal, pero en mi caso, una de las grandes razones por las que creé el blog es para aprender. Y está buenísimo cuando alguien te corrige y aprendés algo nuevo.
¿A qué viene todo esto? Hace un tiempo (7 de abril) escribí en Twitter: " Si haces un for hasta 6.000.000.000, la computadora se tranca...". Y me faltó detallar un poco más a qué me refería, ya que recibí el siguiente correo de fcr:
de fcr
para fernando[arroba]picandocodigo.net
fecha 9 de abril de 2008 14:00
asunto respuesta a mensaje en twitter
¡Mentira, no se tranca nada!
fran@jariola:~/proj/video% cat for_loco.c #include <stdlib.h> int main(void){ for(uint64_t i=0; i<6000000000; i++); } fran@jariola:~/proj/video% cc for_loco.c -o for_loco -std=c99 -O2 fran@jariola:~/proj/video% time ./for_loco ./for_loco 0,00s user 0,00s system 66% cpu 0,001 total fran@jariola:~/proj/video% |
Sin embargo, me faltó detallar las condiciones de mi experiencia. Para ser más preciso, mi mensaje debió decir "Si hacés un for hasta 6.000.000.000 programando en una máquina con Windows XP, en Visual Studio con el framework .NET 2.0, y ejecutás la aplicación que contiene dicho código con unas cuantas aplicaciones más abiertas, la máquina se cuelga". Salió de una experiencia durante mi jornada laboral de ese día.
Si pruebo el código de fcr en mi máquina, con Debian GNU/Linux, y compilando el código en C por consola, efectivamente no se tranca:
fernando@nando-debian:~/DEVEL/C/for$ cc forLoco.c -o for_loco -std=c99 -O2 fernando@nando-debian:~/DEVEL/C/for$ time ./for_loco real 0m0.001s user 0m0.000s sys 0m0.000s fernando@nando-debian:~/DEVEL/C/for$ |
Bien, además de aprender que no se tranca, aprendí un par de cosas más:
-En sistemas GNU es equivalente escribir "gcc" o "cc" gcc.
-El parámetro "-std=c99" le dice a gcc que intente usar el estándar C99.
-El parámetro "O" (en éste caso "-O2"), es para usar la optimización de GCC. -On, donde n es el nivel de optimización. También está -Os que optimiza para que el binario quede lo más chico posible.
Respecto a éste último punto, a rasgos muy generales puedo decir que GCC provee varias opciones para aumentar la velocidad o reducir el tamaño de los archivos ejecutables que genera. Éste tema tengo que darle un poco más de estudio.
Por ejemplo, miren el resultado si compilo el mismo código, sin el parámetro de optimización:
fernando@nando-debian:~/DEVEL/C/for$ cc forLoco.c -o for_loco -std=c99 fernando@nando-debian:~/DEVEL/C/for$ time ./for_loco real 0m29.273s user 0m29.182s sys 0m0.012s fernando@nando-debian:~/DEVEL/C/for$ |
Del IRC:
<fcr> fbt: nadie compila sin el -O2
<fcr> mirá si te asfixiás
Y todo esto lo aprendí por una pavada nomás, y unos minutos en irc. Si tendré C por aprender...
Juan Funez 25 abril. 2008 - 01:34
¿Quien más sino Francisco?
Lo de CC y ‘-std=c99? no tenia idea, lo de -O2 si, yo usaba -O3 para las tareas de facultad y de ahí me quedo.
Esta muy bueno el comentario del IRC.
Saludos.
takedown 25 abril. 2008 - 02:59
bueno bueno bueno… sigo hace bastante (año pasado) el blog y la verdad, siempre es bueno leerte…
esta vez me decidi a comentar ya que estaba programando en C, algo no salia bien y vi que mi agregador de Rss (aka akregator) titilaba con 1 nuevo item…
Y ¬¬
C
C
C
C
C
C
¬¬
Dios que lenguaje precioso… a uno lo hace revolcarse ^^
en fin, a tener en cuenta el -O2 😛 o el -Os pero estaria bueno encontrar info sobre cual valor darle (el mas correcto)
Angelus 25 abril. 2008 - 06:36
Esta bueno locos , la verdad eso de las opciones de compilacion vienen bien saberlas ..
javi 25 abril. 2008 - 07:18
Por qué el compilador no elimina el bucle? podrías poner el desensamblado?
YoNoSoyTu 25 abril. 2008 - 07:59
Deberías poner contenido dentro del bucle, con -O2 (o posiblemente con -O1) GCC está optimizando tu código y posiblemente destruya ese bucle sin contenido, dejando tu programa en nada (por eso tarda tan poco).
Ponle una suma o asigna el contador del bucle a una variable para que veas que sucede.
daniel 25 abril. 2008 - 19:24
pasandole -O al gcc ya elimina el bucle.
soullost 26 abril. 2008 - 00:53
Interesante. En gentoo siempre se especifica los flags de optimización y anexas.
CFLAGS="-O2 -march=pentium4 -fomit-frame-pointer -pipe -msse2 -mfpmath=sse"
CHOST="i686-pc-linux-gnu"
MAKEOPTS="-j2"
Por acá opciones recomendadas para varios procesadores: http://gentoo-wiki.com/Safe_Cflags
soullost 26 abril. 2008 - 00:56
Qué pasa con mi comentario? :S
SpamLoco 27 abril. 2008 - 19:45
C es como un tanque de guerra, imparable xD
Mauricio 16 mayo. 2010 - 13:49
Hola,
Ayer me encontré esta entrada a tu blog, y decidí hacer una pequeña prueba,a verq ue pasaba si le agregaba un printf() a la salida estandar … y me sorprendio bastante el resultado…
<pre lang= "c"
raul@raul-desktop:~$ cat for_loco.c
#include
#include
#include
int main(void){
uint64_t i;
for(i=0ll; i /dev/null
real 21m21.155s
user 17m18.190s
sys 0m6.180s
raul@raul-desktop:~$
¿loco no? Tal vez cuando el for esta vacío simplemente lo elimina en la optimización…
Aclaro: no tengo más conocimientos de c más allá de lo publicado aquí.
Saludos,
Mauricio.
Mauricio 17 mayo. 2010 - 18:19
Corrijo codigo porque salio como el tujem:
cat for_loco.c
#include
#include
#include
int main(void){
uint64_t i;
for(i=0ll; i /dev/null
real 21m21.155s
user 17m18.190s
sys 0m6.180s
fernando 17 mayo. 2010 - 19:01
Qué bueno que los posts “viejos” sigan enganchando 😛
Cómo mostrar código en los comentarios.
anon 11 enero. 2011 - 00:03
y de aquel proyecto con Qt salio algo?
Fernando 11 enero. 2011 - 00:57
No, al final quedó en el olvido como otros tantos proyectos…
anon 11 enero. 2011 - 19:12
lastima 🙁