Hi, Ich compiliere meine Programme auf meiner Athlon-SMP-Maschine mit make -j2 oder -j4, damit beide Prozessoren ausgelastet werden. Das funktioniert auch generell problemlos, bis auf merkwürdige Probleme beim compilieren des Linux-Kernels. Auf einer single CPU Maschine habe ich immer ein "make dep bzImage modules modules_install" angeworfen. Auf der SMP-Maschine bin ich mit "make -j4 dep bzImage modules modules_install" gleich mal ins Schleudern geraten, weil es den Anschein hat, daß dabei die einzelnen make-targets bunt durcheinander gemischt werden. Ich bin dann umgestiegen auf folgendes: "make -j4 dep && make -j4 bzImage && make -j4 modules && make -j4 modules_install". Das schien besser zu funktionieren - jedenfalls hatte ich dann keine unreproduzierbaren Fehler mehr beim maken. Nur habe ich gerade bemerkt, daß mir z.B. das modul-directory mit dem loop.o treiber fehlt, obwohl er konfiguriert und auch compiliert war. Als ich dann ein weiteres "make modules_install" nachgeschoben habe, war der Treiber dann da. Kurz gefragt: ist ein make -jx beim Linux-Kernel nicht zulässig? Gibt es Fälle, wo make -jx nicht richtig arbeitet? Technische Daten: SuSE 7.2 Pro GNU Make version 3.79.1 vanilla-linux-2.4.19 (SMP/4GB) Thomas.
Thomas Hofer wrote:
Ich compiliere meine Programme auf meiner Athlon-SMP-Maschine mit make -j2 oder -j4, damit beide Prozessoren ausgelastet werden. Das funktioniert auch generell problemlos, bis auf merkwürdige Probleme beim compilieren des Linux-Kernels.
Auf einer single CPU Maschine habe ich immer ein "make dep bzImage modules modules_install" angeworfen. Auf der SMP-Maschine bin ich mit "make -j4 dep bzImage modules modules_install" gleich mal ins Schleudern geraten, weil es den Anschein hat, daß dabei die einzelnen make-targets bunt durcheinander gemischt werden. Ich bin dann umgestiegen auf folgendes: "make -j4 dep && make -j4 bzImage && make -j4 modules && make -j4 modules_install". Das schien besser zu funktionieren - jedenfalls hatte ich dann keine unreproduzierbaren Fehler mehr beim maken. Nur habe ich gerade bemerkt, daß mir z.B. das modul-directory mit dem loop.o treiber fehlt, obwohl er konfiguriert und auch compiliert war. Als ich dann ein weiteres "make modules_install" nachgeschoben habe, war der Treiber dann da.
Kurz gefragt: ist ein make -jx beim Linux-Kernel nicht zulässig? Gibt es Fälle, wo make -jx nicht richtig arbeitet?
Generell muss man mit der Option -j ein wenig vorsichtig sein. Ob es funktioniert, haengt u.a. davon ab, ob die Makefiles alle richtig ge- schrieben wurden und was genau mit Hilfe der Makefiles gemacht wird. Insbesondere bei rekursiven Aufrufen, wie sie beim Kernel stark vor- kommen, muss man aufpassen. Dazu gibt es auch einen Abschnitt im Manual zu "make"[1], vielleicht solltest Du Dir das mal anschauen. Es koennen AFAIK mitunter sog. "race conditions" auftreten, wenn mehrere Targets gleichzeitig ausgefuehrt werden. So darf ja z.B. erst gelinkt werden, wenn wirklich alle Object-Files erstellt wurden. Vergleicht man das mit der Programmierung in OpenMP, so wird dort an einigen Stellen explizit synchronisiert - wie das make regelt, weiss ich lei- der nicht genau. Da beim Kernel nicht nur compiliert wird, sondern im Laufe der Erstellung auch Dateien angelegt und wieder gelesen oder erneuert werden, ist das sicher sehr anfaellig fuer "race conditions". IMHO macht die Option -j zumindest bei "make dep" und "make modules_install" wenig Sinn - die Hauptzeit geht fuer das Compilieren drauf, d.h. dort kannst Du die Option getrost weglassen. By the way, nach "make dep" folgt normalerweise ein "make clean" - laesst Du das absichtlich weg? Gruesse, Thomson [1] es ist von R. Stallman und R. McGrath und gibt es in verschiedenen Formaten unter http://www.gnu.org/ -- Thomas Hertweck, Dipl.-Geophys. Geophysikalisches Institut, Universitaet Karlsruhe (TH)
On Monday 30 December 2002 15:01, Thomas Hertweck wrote:
Manual zu "make"[1], vielleicht solltest Du Dir das mal anschauen.
Danke, guter Hinweis.
IMHO macht die Option -j zumindest bei "make dep" und "make modules_install" wenig Sinn - die Hauptzeit geht fuer das Compilieren drauf, d.h. dort kannst Du die Option getrost weglassen.
Das ist klar; ich hab sie nur "pro forma" hingeschrieben, weil ich dachte, die Option wäre unproblematisch.
By the way, nach "make dep" folgt normalerweise ein "make clean" - laesst Du das absichtlich weg?
Ist Absicht - ich liebe Schwierigkeiten :) Bis jetzt hat es bei mir immer ohne make clean funktioniert. Ich habe aber das Gefühl, daß sich die massiven compile-Probleme, die ich gerade mit dem neuen 2.4.20er hatte, auf das Fehlen des make clean zurückführen lassen. Ich bin nun auf folgende Formel umgestiegen: make dep clean && make -j4 bzImage modules && make modules_install Sieht schon viel besser aus... Grüße, Thomas.
Thomas Hofer wrote:
On Monday 30 December 2002 15:01, Thomas Hertweck wrote: [...]
IMHO macht die Option -j zumindest bei "make dep" und "make modules_install" wenig Sinn - die Hauptzeit geht fuer das Compilieren drauf, d.h. dort kannst Du die Option getrost weglassen.
Das ist klar; ich hab sie nur "pro forma" hingeschrieben, weil ich dachte, die Option wäre unproblematisch.
Hmm, unproblematisch ist diese Option wohl eher nicht. Falls Du Dich mal mit Programmierung fuer Parallelrechner auseinander setzt, dann wirst Du das merken - "race conditions" sind da eine tueckische Angelegenheit! Kleines Beispiel: Du hast ein Shared-Memory-System und moechtest immer etwas zur Variablen a dazu addieren. Das ganze verteilst Du auf mehrere Prozessoren, die Variable a wird aber von allen geteilt. Nun ist a=1 und das parallel laufende Programm moechte nun gleich- zeitig vom Thread auf Proz1 eine 2 und vom Thread auf Proz2 eine 3 zur Variablen a hinzuaddieren. Was ist das Ergebnis? Wenn beide es wirklich gleichzeitig versuchen, dann sieht Proz1 a=1+2 und Proz2 sieht a=1+3, und letztendlich ist es Zufall, was nachher in der Variablen a steht, naemlich 3 oder 4. Aber beides ist falsch, denn es muesste a=1+2+3=6 drin stehen. Deswegen muss man dafuer sorgen, dass z.B. immer nur ein Zahl zu einem Zeitpunkt zu a hinzu addiert werden kann - bei OpenMP kann man das mit sog. Pragmas (Preproces- sor-Anweisungen) realisieren, in diesem Falle braeuchte man ein sog. "atomic". Das nur mal als ganz einfaches Beispiel. Bei Make- files duerfte es sich aehnlich verhalten - es muesste ja sicherge- stellt werden, dass das Target zur Erstellung aller Object-Files beendet ist, bevor das Target zum Linken aufgerufen wird. Sonst kommt es zu Fehlern. Solange ich nur compiliere und Object-Files erzeuge (gcc -c) kann ich das im Prinzip locker parallel laufen lassen. Beim Kernel werden aber eben auch "unterwegs" Dateien an- gelegt, wieder gelesen, etc. - das macht es anfaellig fuer "race conditions".
By the way, nach "make dep" folgt normalerweise ein "make clean" - laesst Du das absichtlich weg?
Ist Absicht - ich liebe Schwierigkeiten :) Bis jetzt hat es bei mir immer ohne make clean funktioniert. Ich habe aber das Gefühl, daß sich die massiven compile-Probleme, die ich gerade mit dem neuen 2.4.20er hatte, auf das Fehlen des make clean zurückführen lassen. Ich bin nun auf folgende Formel umgestiegen:
make dep clean && make -j4 bzImage modules && make modules_install
Das sieht besser aus. Ich wuerde das "make clean" nicht weglassen Da- bei werden die alten Object-Files geloescht, es wird der alte compi- lierte Kernel + System.map aus dem Kernelquellbaum geloescht, es wird compile.h (enthaelt Infos ueber Compiler und Uhrzeit der Kernelerstel- kung) geloescht, usw. Das sorgt dann auf alle Faelle dafuer, dass alle Object-Files neu erstellt werden _muessen_. Ausserdem ist das heutzu- tage bei schnellen Rechnern kein groesseres Problem mehr, hier compi- liert ein Kernel mit allem Schnickschnack in ein paar Minuten durch :) Gruesse, Thomson -- Thomas Hertweck, Dipl.-Geophys. Geophysikalisches Institut, Universitaet Karlsruhe (TH)
Hallo, Thomas Hofer wrote:
Hi,
Ich compiliere meine Programme auf meiner Athlon-SMP-Maschine mit make -j2 oder -j4, damit beide Prozessoren ausgelastet werden. Das funktioniert auch generell problemlos, bis auf merkwürdige Probleme beim compilieren des Linux-Kernels.
Auf einer single CPU Maschine habe ich immer ein "make dep bzImage modules modules_install" angeworfen. Auf der SMP-Maschine bin ich mit "make -j4 dep bzImage modules modules_install" gleich mal ins Schleudern geraten, weil es den Anschein hat, daß dabei die einzelnen make-targets bunt durcheinander gemischt werden. Ich bin dann umgestiegen auf folgendes: "make -j4 dep && make -j4 bzImage && make -j4 modules && make -j4 modules_install". Das schien besser zu funktionieren - jedenfalls hatte ich dann keine unreproduzierbaren Fehler mehr beim maken. Nur habe ich gerade bemerkt, daß mir z.B. das modul-directory mit dem loop.o treiber fehlt, obwohl er konfiguriert und auch compiliert war. Als ich dann ein weiteres "make modules_install" nachgeschoben habe, war der Treiber dann da.
Kurz gefragt: ist ein make -jx beim Linux-Kernel nicht zulässig? Gibt es Fälle, wo make -jx nicht richtig arbeitet?
make -j4 dep bzImage führt dazu, das bereits compilliert wird, ehe alle deps existieren. Das geht schief. Bei dep bringt -j4 nichts und ebenfalls bei modules_install Ich mache immer make dep make -j4 bzImage modules make modules_install Es müßte aber auch make dep && make -j4 bzImage modules && make modules_install gehen. Übrigens geht make -j4 auch bei Dingen schief, die sich beim Compilieren noch configurieren (dep mit autoconf) wie z.B. mozilla. Jürgen
participants (3)
-
Juergen Rienaecker
-
Thomas Hertweck
-
Thomas Hofer