Manchmal ist es praktisch, etwas mit einem kleinen C-Programm zu simulieren, das einen großen Teil des statischen Speichers verwendet. Mir ist aufgefallen, dass nach dem Umstieg auf Fedora 15 das Programm einen nahm lang Zeit zu kompilieren. Wir reden hier von 30s vs. 0,1s. Noch seltsamer war, dass ld (der Linker) die CPU maximal auslastete und langsam anfing, den gesamten verfügbaren Speicher zu verbrauchen. Nach einigem Herumfummeln gelang es mir, eine Korrelation zwischen diesem neuen Problem und der Größe meiner Auslagerungsdatei zu finden. Hier ist ein Beispielprogramm für die Zwecke dieser Diskussion:
#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);
}
Dieses Programm hat ein riesiges Array mit einer deklarierten Größe von etwa 200 * 8 MB = 1,6 GB statischem Speicher. Das Kompilieren dieses Programms nimmt übermäßig viel Zeit in Anspruch:
[me@bleh]$ time gcc HugeTest.c
real 0m12.954s
user 0m6.995s
sys 0m3.890s
[me@bleh]$
13s Für ein C-Programm mit ~13 Zeilen!? Das ist nicht richtig. Die Schlüsselzahl ist die Größe des statischen Speicherplatzes. Sobald es größer als der gesamte Swap Space ist, beginnt es schnell wieder zu kompilieren. Zum Beispiel habe ich 5,3 GB Auslagerungsspeicher, also ergibt das Ändern von GIANT_SIZE auf (1000 * M) die folgende Zeit:
[me@bleh]$ time gcc HugeTest.c
real 0m0.087s
user 0m0.026s
sys 0m0.027s
Ah, das ist eher so! Um mich (und sich selbst, wenn Sie das zu Hause versuchen) weiter davon zu überzeugen, dass der Auslagerungsspeicher tatsächlich die magische Zahl war, habe ich versucht, den verfügbaren Auslagerungsspeicher auf wirklich massive 19 GB zu ändern und zu versuchen, die (1000 * M) -Version erneut zu kompilieren :
[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
Es war nicht einmal nach 4,5 Minuten abgeschlossen!
Offensichtlich macht der Linker hier etwas falsch, aber ich weiß nicht, wie ich das umgehen soll, außer das Programm neu zu schreiben oder mit dem Auslagerungsbereich herumzuspielen. Ich würde gerne wissen, ob es eine Lösung gibt oder ob ich auf einen geheimnisvollen Fehler gestoßen bin.
Die Programme kompilieren und laufen übrigens alle korrekt, unabhängig von all dem Swap-Geschäft.
Als Referenz finden Sie hier einige möglicherweise relevante Informationen:
[]$ 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: Wenn der (große) statische Speicher eines AC-Programms etwas kleiner ist als der verfügbare Auslagerungsspeicher, braucht der Linker ewig, um das Programm zu verknüpfen. Es ist jedoch ziemlich bissig, wenn der statische Abstand geringfügig ist größer als der verfügbare Auslagerungsspeicher. Was ist damit!?
Dupliziert diese Frage: stackoverflow.com/questions/4978664/…
– prätorianischer Droide
22. November 2011 um 21:03 Uhr
@praetoriandroid Ausgezeichneter Fund, es tut mir leid, dass ich das nicht früher gesehen habe. Die Antwort in dieser Frage erklärt gut, warum dies wahrscheinlich passiert, aber ich werde auf etwas weiteres hinweisen, das meine Frage impliziert – warum kann der Linker für etwas, das etwas größer als der verfügbare Auslagerungsspeicher ist, so flink sein?
– Rookie
22. November 2011 um 21:49 Uhr
@Rooke: Es scheint wahrscheinlich, dass die Zuordnung des gesamten Objekts fehlschlägt, wenn nicht genügend Auslagerungsspeicher verfügbar ist, und der Linker auf eine andere Methode zurückgreift, die tatsächlich schneller ausgeführt wird (da er überhaupt nicht in den Auslagerungsbereich eintaucht).
– Café
22. November 2011 um 23:16 Uhr
Einige weitere Informationen, die nützlich sein könnten: Ich habe überhaupt keinen Swap und die Kompilierung des obigen Codes mit 800 MB Puffer dauert auf meinem PC etwa 6,7 Sekunden. Das Ausführen eines Programms, das nur dynamisch Puffer der gleichen Größe zuweist und auf Null setzt, dauert etwa 0,7 Sekunden – fast 10-mal weniger (tatsächlich 9,5). Wenn die Puffergröße zweimal kleiner wird, werden beide Zeiten zweimal kleiner (3,4 s gegenüber 0,36 s), aber das Verhältnis ist dasselbe – etwa das 9,5-fache.
– prätorianischer Droide
23. November 2011 um 6:12 Uhr
@praetoriandroid Es hört sich so an, als würden Sie meine Beobachtung zur Verbindungszeit bestätigen. Mir ist klar, dass die dynamische Speicherzuweisung + das Nullen des Speichers schneller ist, wenn der Linker träge ist. Das interessiert mich nicht wirklich. Meine Frage ist, warum der Linker nicht zippy sein kann alle die Zeit.
– Rookie
24. November 2011 um 16:03 Uhr
Ich kann dies auf einem Ubuntu 10.10-System reproduzieren (GNU ld (GNU Binutils for Ubuntu) 2.20.51-system.20100908), und ich glaube, ich habe Ihre Antwort. Zunächst etwas Methodik.
Nachdem ich bestätigt hatte, dass mir dies in einer kleinen VM (512 MB RAM, 2 GB Swap) passiert, entschied ich mich von hier aus, dass es am einfachsten wäre, gcc zu straceen und zu sehen, was genau los war, als alles zum Teufel ging:
Es scheint, dass es so aussieht, wie wir vielleicht vermutet haben ld versucht tatsächlich, anonym mmap den gesamten statischen Speicherplatz dieses Arrays (oder möglicherweise das gesamte Programm, es ist schwer zu sagen, da der Rest des Programms so klein ist, dass alles in diese zusätzlichen 4096 passen könnte).
Das ist alles schön und gut, aber warum funktioniert es, wenn wir den verfügbaren Swap auf dem System überschreiten? Wenden wir uns um swapoff und Renn strace -f wieder…
Es überrascht nicht, dass ld dasselbe zu tun scheint, was es beim letzten Mal versucht hat, nämlich den gesamten Raum zu mmappingen. aber das System kann das nicht mehr, es fällt aus! ld versucht es erneut, und es schlägt wieder fehl, dann macht ld etwas Unerwartetes … es geht mit weniger Speicher weiter.
Seltsam, ich schätze, wir sollten uns das besser ansehen das ld Code dann. Verdammt, es macht kein explizites mmap. Das muss aus einem einfachen Alten kommen malloc. Wir müssen ld mit einigen Debug-Symbolen bauen, um dies aufzuspüren. Leider verschwand das Problem, als ich bin-utils 2.21.1 erstellte. Vielleicht wurde es in neueren Versionen von bin-utils behoben?
Genau das wollte ich wissen, danke! Ich werde am Montag ein paar Nachforschungen anstellen, also verzeihen Sie eine kleine Verzögerung mit der Belohnung. In der Tat “mit der GNU C-Bibliothek verwendet das enthaltene Malloc automatisch mmap, wo es angebracht ist”, was meiner Meinung nach ungefähr 2 MB beträgt (ich habe vergessen, woher ich diese Nummer bekomme, verzeihen Sie mir). gnu.org/s/hello/manual/libc/Memory_002dmapped-I_002fO.html
– Rookie
28. November 2011 um 3:59 Uhr
Ich beobachte dieses Verhalten nicht (mit Debian/Sid/AMD64 auf einem 8-GB-Desktop, gcc 4.6.2, binutils gold ld (GNU Binutils for Debian 2.22) 1.11). Hier ist das geänderte Programm (Anzeige seiner Speicherkarte mit 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);
}
Hier ist seine Zusammenstellung:
% 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
und seine Ausführung:
% 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
Ich glaube, dass die Installation eines aktuellen GCC (z AGB 4.6) mit einer binutils Gold-Linker ist für solche Programme von Bedeutung.
Ich höre keinen Austausch beteiligt.
Beachten Sie, dass ich einfach gefragt habe -O Optimierung.
– Basile Starynkevitch
22. November 2011 um 20:57 Uhr
Aber auch ohne jegliche Optimierung bleiben die Kompilierung und Ausführung nahezu augenblicklich.
– Basile Starynkevitch
22. November 2011 um 21:12 Uhr
Danke, dass du das getestet hast, Basile. Denken Sie daran, dass ich nicht so sehr an den Laufzeiteigenschaften interessiert bin, wie daran, warum der Linker beschließt, bestimmte Dinge zu tun. Das Kompilieren mit Ihrer Einstellung von GIANT_SIZE (2000 * M) ist auch auf meiner Box bissig. Der Schlüssel versucht, die Größe des Arrays auf etwas knapp unter der Gesamtzahl einzustellen Tauschen Größe. Beachten Sie auch, dass meine binutils-Version 2.21.51.0.6-6.fc15 ist, von der ich glaube, dass sie den sogenannten Gold-Linker enthält. Ob es tatsächlich genutzt wird, weiß ich allerdings nicht.
– Rookie
22. November 2011 um 21:56 Uhr
Rooke, kannst du hinzufügen -v Option zu Ihrem Compile&Link-Befehl `gcc HugeTest.c` und gcc gibt jedes Unterprogramm, das es ausführt, mit allen Optionen aus.
– osgx
23. November 2011 um 2:36 Uhr
Der einzige Unterschied, den ich zwischen Basiles Linker und meinem sehen kann, ist die Option ‘–hash-style=both’. Auf meiner Fedora-Box ist es –hash-style=gnu. Ich habe eine zufriedenstellende Erklärung dafür gefunden (siehe Link), aber ich bezweifle, dass dies Auswirkungen hat. sites.google.com/site/avinesh/…
– Rookie
23. November 2011 um 16:27 Uhr
Roter Komet
Ich habe mein OpenSuse 11.4 quälend getestet (in einer Woche für 12.1)
Ich habe 4 GiB RAM + 2 GiB Swap und habe keine ernsthafte Verlangsamung bemerkt, das System könnte manchmal kaputt gehen, aber die Kompilierzeit war trotzdem kurz.
Die längste war 6 Sekunden bei starkem Austausch.
[tester@ulises ~]$ free -m
total used free shared buffers cached
Mem: 3456 3426 30 0 4 249
-/+ buffers/cache: 3172 284
Swap: 2055 1382 672
[tester@ulises ~]$ 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
[tester@ulises ~]$ free -m
total used free shared buffers cached
Mem: 3456 3389 67 0 5 289
-/+ buffers/cache: 3094 362
Swap: 2055 1455 599
[tester@ulises ~]$ free -m
total used free shared buffers cached
Mem: 3456 3373 82 0 4 264
-/+ buffers/cache: 3104 352
Swap: 2055 1442 612
[tester@ulises ~]$ 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
[tester@ulises ~]$ 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
[tester@ulises ~]$ free -m
total used free shared buffers cached
Mem: 3456 3376 79 0 4 252
-/+ buffers/cache: 3119 336
Swap: 2055 1436 618
[tester@ulises ~]$ 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
Zwischen dem Ausführen habe ich Virtualbox Box VMs, Eclipse, große PDF-Dateien, mi Firefox allein mit mehr als 800 MiB geladen und entladen. Ich bin nicht ans Limit gegangen, sonst würden viele Apps vom OS gekillt werden. Es hat eine Vorliebe für das Töten von Firefox.. 🙂
Ich bin auch bis zum Äußersten gegangen, um zu definieren:
#define M 1048576
#define GIANT_SIZE (20000*M)
und selbst dann ändert sich nichts wesentlich.
[tester@ulises ~]$ 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
Bearbeiten: Ich habe die Verwendung von Fedora16 auf einer VM mit 512 MiB RAM und 1,5 GiB Swap erneut getestet, und die Dinge waren ähnlich, mit Ausnahme einer Fehlermeldung in meiner “Maximum-Stress-Version”, bei der dem Array 20000 Megabyte zugewiesen wurden. Der Fehler besagt, dass die Arraygröße negativ war.
[ricardo@localhost ~]$ 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
Die gleiche Antwort tritt in der Opensuse 12.1 VM auf. Die Installation von Fedora 16 war sehr langsam und speicherhungrig (während der Installation musste ich 800 MiB im Vergleich zu OpenSuse 512 MiB verwenden), ich konnte Swapoff auf Fedora nicht verwenden, da es viel Auslagerungsspeicher belegte. Ich hatte keine Trägheit oder Speicherprobleme unter OpenSuse 12.1 und . Beide haben im Wesentlichen die gleichen Versionen von Kernel, gcc usw. Beide verwenden Standardinstallationen mit KDE als Desktop-Umgebung
Ich konnte Ihre Probleme nicht reproduzieren. Möglicherweise handelt es sich um ein gcc-bezogenes Problem. Versuchen Sie, eine ältere Version wie 4.5 herunterzuladen und sehen Sie, was passiert
14016900cookie-checkLinkerleistung im Zusammenhang mit Swap Space?yes
Dupliziert diese Frage: stackoverflow.com/questions/4978664/…
– prätorianischer Droide
22. November 2011 um 21:03 Uhr
@praetoriandroid Ausgezeichneter Fund, es tut mir leid, dass ich das nicht früher gesehen habe. Die Antwort in dieser Frage erklärt gut, warum dies wahrscheinlich passiert, aber ich werde auf etwas weiteres hinweisen, das meine Frage impliziert – warum kann der Linker für etwas, das etwas größer als der verfügbare Auslagerungsspeicher ist, so flink sein?
– Rookie
22. November 2011 um 21:49 Uhr
@Rooke: Es scheint wahrscheinlich, dass die Zuordnung des gesamten Objekts fehlschlägt, wenn nicht genügend Auslagerungsspeicher verfügbar ist, und der Linker auf eine andere Methode zurückgreift, die tatsächlich schneller ausgeführt wird (da er überhaupt nicht in den Auslagerungsbereich eintaucht).
– Café
22. November 2011 um 23:16 Uhr
Einige weitere Informationen, die nützlich sein könnten: Ich habe überhaupt keinen Swap und die Kompilierung des obigen Codes mit 800 MB Puffer dauert auf meinem PC etwa 6,7 Sekunden. Das Ausführen eines Programms, das nur dynamisch Puffer der gleichen Größe zuweist und auf Null setzt, dauert etwa 0,7 Sekunden – fast 10-mal weniger (tatsächlich 9,5). Wenn die Puffergröße zweimal kleiner wird, werden beide Zeiten zweimal kleiner (3,4 s gegenüber 0,36 s), aber das Verhältnis ist dasselbe – etwa das 9,5-fache.
– prätorianischer Droide
23. November 2011 um 6:12 Uhr
@praetoriandroid Es hört sich so an, als würden Sie meine Beobachtung zur Verbindungszeit bestätigen. Mir ist klar, dass die dynamische Speicherzuweisung + das Nullen des Speichers schneller ist, wenn der Linker träge ist. Das interessiert mich nicht wirklich. Meine Frage ist, warum der Linker nicht zippy sein kann alle die Zeit.
– Rookie
24. November 2011 um 16:03 Uhr