2011-11-22 15 views
40

A veces es útil simular algo con un pequeño programa en C que utiliza una gran cantidad de memoria estática. Me di cuenta después de cambiar a Fedora 15 el programa tomó un largo tiempo a compilación . Estamos hablando de 30 s contra 0.1 s. Aún más extraño fue que ld (el enlazador ) estaba maximizando la CPU y lentamente comenzó a comer toda la memoria disponible. Después de un poco de manipulación, logré para encontrar una correlación entre este nuevo problema y el tamaño de mi archivo swap . He aquí un programa de ejemplo para los propósitos de esta discusión:¿Rendimiento del enlazador relacionado con el espacio de intercambio?

#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 
#define M 1000000 
#define GIANT_SIZE (200*M) 

size_t g_arr[GIANT_SIZE]; 

int main(int argc, char **argv){ 
    int i; 
    for(i = 0; i<10; i++){ 
     printf("This should be zero: %d\n",g_arr[i]); 
    } 
    exit(1); 
} 

Este programa cuenta con una red gigante que tiene un tamaño declarado de alrededor 200 * 8 MB = 1,6 GB de memoria estática. La elaboración de este programa toma un cantidad excesiva de tiempo:

[[email protected]]$ time gcc HugeTest.c 

real 0m12.954s 
user 0m6.995s 
sys 0m3.890s 

[[email protected]]$ 

13s Para una línea de programa 13 ~ C !? Eso no está bien. El número de clave es el tamaño del espacio de memoria estática. Tan pronto como es más grande que el espacio de intercambio total , comienza a compilarse rápidamente nuevamente. Por ejemplo, yo tengo 5.3GB de espacio de intercambio, por lo que cambiar a GIANT_SIZE (1000 * M) da el siguiente tiempo:

[[email protected]]$ time gcc HugeTest.c 

real 0m0.087s 
user 0m0.026s 
sys 0m0.027s 

Ah, eso es más como! Para convencerme aún más a mí mismo (y a usted mismo, si está intentando esto en casa) de que el espacio de intercambio era efectivamente el número mágico, traté de cambiar el espacio de intercambio disponible por uno realmente masivo 19GB y tratando de compilar el (1000 * M) versión de nuevo:

[[email protected]]$ ls -ali /extraswap 
5986 -rw-r--r-- 1 root root 14680064000 Jul 26 15:01 /extraswap 
[[email protected]]$ sudo swapon /extraswap 
[[email protected]]$ time gcc HugeTest.c 

real 4m28.089s 
user 0m0.016s 
sys 0m0.010s 

¡Ni siquiera se completó después de 4.5 minutos!

Claramente, el enlazador está haciendo algo mal aquí, pero no sé cómo para evitar esto, además de reescribir el programa o perder el tiempo con el espacio de intercambio. Me encantaría saber si hay una solución, o si tengo tropecé con algún error arcano.

Por cierto, todos los programas compilan y se ejecutan correctamente, independientemente de todo el negocio de intercambio.

Como referencia, he aquí algo de información posiblemente relevante:

[]$ ulimit -a 

core file size   (blocks, -c) 0 
data seg size   (kbytes, -d) unlimited 
scheduling priority    (-e) 0 
file size    (blocks, -f) unlimited 
pending signals     (-i) 27027 
max locked memory  (kbytes, -l) 64 
max memory size   (kbytes, -m) unlimited 
open files      (-n) 1024 
pipe size   (512 bytes, -p) 8 
POSIX message queues  (bytes, -q) 819200 
real-time priority    (-r) 0 
stack size    (kbytes, -s) 8192 
cpu time    (seconds, -t) unlimited 
max user processes    (-u) 1024 
virtual memory   (kbytes, -v) unlimited 
file locks      (-x) unlimited 

[]$ uname -r 

2.6.40.6-0.fc15.x86_64 

[]$ ld --version 

GNU ld version 2.21.51.0.6-6.fc15 20110118 
Copyright 2011 Free Software Foundation, Inc. 
This program is free software; you may redistribute it under the terms of 
the GNU General Public License version 3 or (at your option) a later version. 
This program has absolutely no warranty. 

[]$ gcc --version 

gcc (GCC) 4.6.1 20110908 (Red Hat 4.6.1-9) 
Copyright (C) 2011 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

[]$ cat /proc/meminfo 
MemTotal:  3478272 kB 
MemFree:   1749388 kB 
Buffers:   16680 kB 
Cached:   212028 kB 
SwapCached:  368056 kB 
Active:   489688 kB 
Inactive:   942820 kB 
Active(anon):  401340 kB 
Inactive(anon): 803436 kB 
Active(file):  88348 kB 
Inactive(file): 139384 kB 
Unevictable:   32 kB 
Mlocked:    32 kB 
SwapTotal:  19906552 kB 
SwapFree:  17505120 kB 
Dirty:    172 kB 
Writeback:    0 kB 
AnonPages:  914972 kB 
Mapped:   60916 kB 
Shmem:    1008 kB 
Slab:    55248 kB 
SReclaimable:  26720 kB 
SUnreclaim:  28528 kB 
KernelStack:  3608 kB 
PageTables:  63344 kB 
NFS_Unstable:   0 kB 
Bounce:    0 kB 
WritebackTmp:   0 kB 
CommitLimit: 21645688 kB 
Committed_AS: 11208980 kB 
VmallocTotal: 34359738367 kB 
VmallocUsed:  139336 kB 
VmallocChunk: 34359520516 kB 
HardwareCorrupted:  0 kB 
AnonHugePages: 151552 kB 
HugePages_Total:  0 
HugePages_Free:  0 
HugePages_Rsvd:  0 
HugePages_Surp:  0 
Hugepagesize:  2048 kB 
DirectMap4k:  730752 kB 
DirectMap2M:  2807808 kB 

TL; DR: Cuando el (grande) de memoria estática de programa en C es ligeramente menor que el espacio de intercambio disponible, el enlazador necesita siempre para enlace el programa. Sin embargo, es bastante rápido cuando el espacio estático es ligeramente más grande que el espacio de intercambio disponible. ¿¡Que pasa con eso!?

+0

Duplica esta pregunta: http://stackoverflow.com/questions/4978664/long-compilation-time-for-program-with-static-allocation –

+1

@praetoriandroid Excelente hallazgo, lo siento, no lo vi más temprano. La respuesta en esa pregunta explica muy bien por qué esto probablemente está sucediendo, pero señalaré algo más que mi pregunta implica: ¿por qué el enlazador puede ser tan rápido para algo ligeramente más grande que el espacio de intercambio disponible? – Rooke

+0

@Rooke: parece probable que cuando no hay suficiente espacio de intercambio disponible, la asignación de todo el objeto falla y el enlazador recurre a un método diferente que realmente se ejecuta más rápido (debido a que no se sumerge en el intercambio en absoluto). – caf

Respuesta

23

. Puedo reproducir esto en un sistema Ubuntu 10.10 (GNU ld (GNU Binutils for Ubuntu) 2.20.51-system.20100908), y creo que tengo su respuesta. Primero, algo de metodología.

Después de confirmar que esto me sucede en una pequeña máquina virtual (512MB ram, 2GB swap), de aquí decidí que lo más fácil sería dirigirme a gcc y ver qué sucedía exactamente cuando todo se fue al infierno:

~# strace -f gcc swap.c 

iluminó el siguiente:

vfork()         = 3589 
[pid 3589] execve("/usr/lib/gcc/x86_64-linux-gnu/4.4.5/collect2", ["/usr/lib/gcc/x86_64-linux-gnu/4."..., "--build-id", "--eh-frame-hdr", "-m", "elf_x86_64", "--hash-style=gnu", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o", "swap", "-z", "relro", "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., ...], [/* 26 vars */]) = 0 

... 

[pid 3589] vfork()      = 3590 

... 

[pid 3590] execve("/usr/bin/ld", ["/usr/bin/ld", "--build-id", "--eh-frame-hdr", "-m", "elf_x86_64", "--hash-style=gnu", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o", "swap", "-z", "relro", "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., ...], [/* 27 vars */]) = 0  

... 

[pid 3590] lseek(13, 4096, SEEK_SET) = 4096 
[pid 3590] read(13, ".\[email protected]\0\0\0\0\0>\[email protected]\0\0\0\0\0N\[email protected]\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096 
[pid 3590] mmap(NULL, 1600004096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1771931000 
<system comes to screeching halt> 

parecería que, como podríamos haber sospechado, parece que ld en realidad está tratando de forma anónima mmap todo el espacio de memoria estática de esta matriz (o, posiblemente, El e ntire program, es difícil de decir, ya que el resto del programa es tan pequeño, podría encajar en ese 4096 extra).

Así que eso está muy bien, pero ¿por qué funciona cuando excedemos el intercambio disponible en el sistema? Vamos a convertir swapoff y correr de nuevo ... strace -f

[pid 3618] lseek(13, 4096, SEEK_SET) = 4096 
[pid 3618] read(13, ".\[email protected]\0\0\0\0\0>\[email protected]\0\0\0\0\0N\[email protected]\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096 
[pid 3618] mmap(NULL, 1600004096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory) 
[pid 3618] brk(0x60638000)    = 0x1046000 
[pid 3618] mmap(NULL, 1600135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory) 
[pid 3618] mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7fd011864000 

... 

Como era de esperar, ld parece hacer la misma cosa que intentó por última vez, a mmap todo el espacio. pero el sistema ya no puede hacer eso, ¡falla! Lo intenta de nuevo, y falla nuevamente, luego hace algo inesperado ... avanza con menos memoria.

Extraño, supongo que será mejor que echemos un vistazo a the ld code. Drat, no hace un explícito mmap. Esto debe provenir del interior de un simple viejo malloc. Tendremos que construir ld con algunos símbolos de depuración para rastrear esto. Desafortunadamente, cuando construí bin-utils 2.21.1 el problema desapareció. Por cierto, ¿ha sido arreglado en versiones más nuevas de bin-utils?

+0

Esto es exactamente lo que quería saber, ¡gracias! Haré algunas investigaciones el lunes, así que perdona un ligero retraso con la recompensa. De hecho, "con la biblioteca C de GNU, el malloc incluido automáticamente usa mmap cuando corresponde", que creo que es de 2MB o menos (se me olvida dónde obtengo ese número, perdóneme). http://www.gnu.org/s/hello/manual/libc/Memory_002dmapped-I_002fO.html – Rooke

0

No observo este comportamiento (con Debian/Sid/AMD64 en un escritorio de 8 Gb, gcc 4.6.2, binutils gold ld (GNU Binutils para Debian 2.22) 1.11). Aquí está el programa cambiado (mostrando su mapa de memoria con pmap).

#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 
#define M 1000000 
#define GIANT_SIZE (2000*M) 
size_t g_arr[GIANT_SIZE]; 
int main(int argc, char **argv){ 
    int i; 
    char cmd[80]; 
    for(i = 0; i<10; i++){ 
     printf("This should be zero: %d\n",g_arr[i*1000]); 
    } 
    sprintf (cmd, "pmap %d", (int)getpid()); 
    system(cmd); 
    exit(0); 
} 

Aquí es su compilación:

% time gcc -v -O big.c -o big 
Using built-in specs. 
COLLECT_GCC=/usr/bin/gcc-4.6.real 
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper 
Target: x86_64-linux-gnu 
Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.2-4' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu 
Thread model: posix 
gcc version 4.6.2 (Debian 4.6.2-4) 
COLLECT_GCC_OPTIONS='-v' '-O' '-o' 'big' '-mtune=generic' '-march=x86-64' 
/usr/lib/gcc/x86_64-linux-gnu/4.6/cc1 -quiet -v -imultilib . -imultiarch x86_64-linux-gnu big.c -quiet -dumpbase big.c -mtune=generic -march=x86-64 -auxbase big -O -version -o /tmp/ccWThBP5.s 
GNU C (Debian 4.6.2-4) version 4.6.2 (x86_64-linux-gnu) 
    compiled by GNU C version 4.6.2, GMP version 5.0.2, MPFR version 3.1.0, MPC version 0.9 
warning: MPFR header version 3.1.0 differs from library version 3.1.0-p3. 
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" 
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../x86_64-linux-gnu/include" 
#include "..." search starts here: 
#include <...> search starts here: 
/usr/lib/gcc/x86_64-linux-gnu/4.6/include 
/usr/local/include 
/usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed 
/usr/include/x86_64-linux-gnu 
/usr/include 
End of search list. 
GNU C (Debian 4.6.2-4) version 4.6.2 (x86_64-linux-gnu) 
    compiled by GNU C version 4.6.2, GMP version 5.0.2, MPFR version 3.1.0, MPC version 0.9 
warning: MPFR header version 3.1.0 differs from library version 3.1.0-p3. 
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 
Compiler executable checksum: 4b128876859f8f310615c7040fa3cb67 
COLLECT_GCC_OPTIONS='-v' '-O' '-o' 'big' '-mtune=generic' '-march=x86-64' 
as --64 -o /tmp/ccm7905b.o /tmp/ccWThBP5.s 
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/ 
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../:/lib/:/usr/lib/ 
COLLECT_GCC_OPTIONS='-v' '-O' '-o' 'big' '-mtune=generic' '-march=x86-64' 
/usr/lib/gcc/x86_64-linux-gnu/4.6/collect2 --build-id --no-add-needed --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o big /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../.. /tmp/ccm7905b.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o 
gcc -v -O big.c -o big 0.07s user 0.01s system 90% cpu 0.089 total 

y su ejecución:

% time ./big 
This should be zero: 0 
This should be zero: 0 
This should be zero: 0 
This should be zero: 0 
This should be zero: 0 
This should be zero: 0 
This should be zero: 0 
This should be zero: 0 
This should be zero: 0 
This should be zero: 0 
8835: ./big 
0000000000400000  4K r-x-- /home/basile/tmp/big 
0000000000401000  4K rw--- /home/basile/tmp/big 
0000000000402000 15625000K rw--- [ anon ] 
00007f2d15a44000 1512K r-x-- /lib/x86_64-linux-gnu/libc-2.13.so 
00007f2d15bbe000 2048K ----- /lib/x86_64-linux-gnu/libc-2.13.so 
00007f2d15dbe000  16K r---- /lib/x86_64-linux-gnu/libc-2.13.so 
00007f2d15dc2000  4K rw--- /lib/x86_64-linux-gnu/libc-2.13.so 
00007f2d15dc3000  20K rw--- [ anon ] 
00007f2d15dc8000 124K r-x-- /lib/x86_64-linux-gnu/ld-2.13.so 
00007f2d15fb4000  12K rw--- [ anon ] 
00007f2d15fe4000  12K rw--- [ anon ] 
00007f2d15fe7000  4K r---- /lib/x86_64-linux-gnu/ld-2.13.so 
00007f2d15fe8000  4K rw--- /lib/x86_64-linux-gnu/ld-2.13.so 
00007f2d15fe9000  4K rw--- [ anon ] 
00007ffff5b5b000 132K rw--- [ stack ] 
00007ffff5bff000  4K r-x-- [ anon ] 
ffffffffff600000  4K r-x-- [ anon ] 
    total   15628908K 
./big 0.00s user 0.00s system 0% cpu 0.004 total 

creo que la instalación de una reciente GCC (por ejemplo, un GCC 4.6) con un oro binutils linker es significativo para tales programas.

No escucho ningún intercambio involucrado.

+0

Tenga en cuenta que solicité la optimización básica '-O'. –

+0

Pero incluso sin ninguna optimización, la compilación y la ejecución se mantienen casi instantáneas. –

+0

Gracias por probar esto, Basile. Tenga en cuenta que no estoy tan interesado en las características de tiempo de ejecución como lo estoy con por qué el vinculador decide hacer ciertas cosas. Compilar esto con su configuración de GIANT_SIZE (2000 * M) también es ágil en mi caja. La clave está tratando de establecer el tamaño de la matriz a algo justo debajo del tamaño * swap * total. También tenga en cuenta que mi versión binutils es 2.21.51.0.6-6.fc15, que creo que incluye el llamado conector de oro.Sin embargo, no sé si realmente se usa. – Rooke

1

Torturé probado mi OpenSuse 11.4 (ir a 12.1 en una semana)

tengo intercambio carnero 4GiB + 2GiB y no se dio cuenta seria más lento, el sistema podría estar destrozando a veces, pero aún así el tiempo de compilación fue corto.

El más largo fue de 6 segundos, mientras que el intercambio pesado.

[[email protected] ~]$ free -m 
      total  used  free  shared buffers  cached 
Mem:   3456  3426   30   0   4  249 
-/+ buffers/cache:  3172  284 
Swap:   2055  1382  672 
[[email protected] ~]$ time cc -Wall -O test2.c 
test2.c: In function ‘main’: 
test2.c:13:2: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘size_t’ 

real 0m6.501s 
user 0m0.101s 
sys  0m0.078s 
[[email protected] ~]$ free -m 
      total  used  free  shared buffers  cached 
Mem:   3456  3389   67   0   5  289 
-/+ buffers/cache:  3094  362 
Swap:   2055  1455  599 
[[email protected] ~]$ free -m 
      total  used  free  shared buffers  cached 
Mem:   3456  3373   82   0   4  264 
-/+ buffers/cache:  3104  352 
Swap:   2055  1442  612 
[[email protected] ~]$ time cc -Wall -O test2.c 
test2.c: In function ‘main’: 
test2.c:13:2: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘size_t’ 

real 0m1.122s 
user 0m0.086s 
sys  0m0.045s 
[[email protected] ~]$ time cc -Wall -O test2.c 
test2.c: In function ‘main’: 
test2.c:13:2: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘size_t’ 

real 0m0.095s 
user 0m0.047s 
sys  0m0.032s 
[[email protected] ~]$ free -m 
      total  used  free  shared buffers  cached 
Mem:   3456  3376   79   0   4  252 
-/+ buffers/cache:  3119  336 
Swap:   2055  1436  618 
[[email protected] ~]$ time cc -Wall -O test2.c 
test2.c: In function ‘main’: 
test2.c:13:2: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘size_t’ 

real 0m0.641s 
user 0m0.054s 
sys  0m0.040s 

entre correr He cargado y descargado, Eclipse, grandes archivos PDF de VirtualBox caja VM, mi firefox usando solo de 800 MiB. No llegué al límite, de lo contrario, muchas aplicaciones serían destruidas por el sistema operativo. Tiene una preferencia por matar a Firefox .. :-)

también fui a la definición extrema:

#define M 1048576 
#define GIANT_SIZE (20000*M) 

e incluso entonces nada cambia significativamente.

[[email protected] ~]$ time cc -Wall -O test2.c 
test2.c:7:14: warning: integer overflow in expression 
test2.c:7:8: error: size of array ‘g_arr’ is negative 
test2.c:7:1: warning: variably modified ‘g_arr’ at file scope 
test2.c: In function ‘main’: 
test2.c:13:2: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘size_t’ 

real 0m0.661s 
user 0m0.043s 
sys  0m0.031s 

Editar: que volver a probar usando Fedora16 en una máquina virtual con 512MiB RAM y swap de 1.5GiB, y las cosas fueron similares a excepción de un mensaje de error en mi "versión máxima tensión", donde 20000 megabytes fueron asignados a la formación. El error dice que el tamaño de la matriz fue negativo.

[[email protected] ~]$ time gcc -Wall test2.c 
test2.c:7:14: warning: integer overflow in expression [-Woverflow] 
test2.c:7:8: error: size of array ‘g_arr’ is negative 
test2.c:7:1: warning: variably modified ‘g_arr’ at file scope [enabled by default] 
test2.c: In function ‘main’: 
test2.c:13:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘size_t’ [-Wformat] 

real 0m1.053s 
user 0m0.050s 
sys  0m0.137s 

La misma respuesta ocurre en opensuse 12.1 VM. El Fedora 16 instaló el verry lento y el hambre de memoria (durante la instalación tuve que usar 800Mib contra OpenSuse 512 MiB), no pude usar el swapoff en Fedora porque estaba usando mucho swap. No tuve lentitud ni problemas de memoria en OpenSuse 12.1 y. Ambos tienen esencialmente las mismas versiones de kernel, gcc, etc. Ambos usan instalaciones comunes con KDE como el entorno de escritorio

No pude reproducir sus problemas, tal vez es un problema relacionado con gcc. Intente descargar una versión anterior como 4.5 y vea lo que sucede

Cuestiones relacionadas