Voici une énigme pour votre ringard plaisir. Il est parfois pratique de se moquer de quelque chose avec un petit programme C qui utilise une grande partie de l' la mémoire statique. Pendant la programmation d'un ces de ces programmes, j'ai remarqué après le changement de Fedora 15 le programme a pris un long temps de compiler. Nous parlons des années 30 contre 0,1 s. Encore plus bizarre était que ld (la l'éditeur de liens) a été maxing sur le CPU et lentement commencé à en manger tous disponibles de la mémoire. Après quelques jouer du violon, dont les détails que j'oublie, j'ai réussi de trouver une corrélation entre ce nouveau problème et la taille de mon swap fichier. Voici un exemple de programme pour les fins de cette discussion:
#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);
}
Ce programme a un tableau géant qui a déclaré une taille d'environ 200*8 MO = 1,6 GO de mémoire statique. La compilation de ce programme prend une quantité excessive de temps:
[me@bleh]$ time gcc HugeTest.c
real 0m12.954s
user 0m6.995s
sys 0m3.890s
[me@bleh]$
13s Pour un ~13 ligne C programme!? Ce n'est pas juste. Le numéro de clé est la la taille de la mémoire statique de l'espace. Dès qu'il est plus grand que le total de l'espace de swap, il commence à compiler rapidement de nouveau. Par exemple, j' ont 5.3 GO d'espace d'échange, de sorte qu'un changement GIANT_SIZE à (1000*M) donne le de temps suivantes:
[me@bleh]$ time gcc HugeTest.c
real 0m0.087s
user 0m0.026s
sys 0m0.027s
Ah, c'est mieux comme ça! Pour convaincre les autres de moi-même (et vous-même, si vous êtes à essayer ceci à la maison) que l'espace d'échange est en effet la magie numéro, j'ai essayé de changer la disposition de l'espace de swap pour un vraiment énorme 19FR et d'essayer de compiler l' (1000*M) version:
[me@bleh]$ ls -ali /extraswap
5986 -rw-r--r-- 1 root root 14680064000 Jul 26 15:01 /extraswap
[me@bleh]$ sudo swapon /extraswap
[me@bleh]$ time gcc HugeTest.c
real 4m28.089s
user 0m0.016s
sys 0m0.010s
Il n'a même pas terminée au bout de 4,5 minutes! (Gardez à l'esprit, chers lecteurs, J'ai dû faire le sacrifice de tout ce temps à l'exécution de cette commande, comme ld commence à manger toute la mémoire disponible, puis commence l'échange, effectivement le gel de l'ordinateur).
Clairement l'éditeur de liens est en train de faire quelque chose de mal ici, mais je ne sais pas comment pour contourner ce d'autre que de la réécriture du programme ou de déconner avec l'espace de swap. J'aimerais savoir si il y a une solution, ou si j'ai suis tombé sur quelques arcanes de bug.
Par ailleurs, les programmes de toutes les compiler et de l'exécuter correctement, indépendante de toute l'activité de swap.
Pour référence, voici quelques éventuellement les informations pertinentes:
[]$ 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: Lorsque le (grand) statique de la mémoire d'un programme c est légèrement inférieure à la disposition de l'espace de swap, l'éditeur de liens prend une éternité à lier le programme. Cependant, il est assez accrocheur lorsque l'espace statique est légèrement plus grande que la disposition de l'espace de swap. Qu'est-ce que!?