Gute Frage (wollte ich auch gerade fragen). Normalerweise verwende ich -O4 (in der Tat aber auch in der Manpage und den info-seiten undokumentiert). Von -O6 habe ich bis dato noch nichts gehoert...
Selbstverständlich gibt es keine 300 Optimierungsstufen !
Soweit ich informiert bin ist die höchste Optimierungsstufe zur Zeit wirklich -O3 (mal abgesehen von -Os - Optimierung auf Größe), alles darüber wird *zur Zeit* wie -O3 behandelt.
Einige Programme benutzen lediglich -O6 & co., weil sie annehmen, dass zukünftige GCC-Versionen entsprechend hohe Optimierungsstufen anbieten und dann auch von den starken Optimierungen profitieren wollen.
Wenn du die CFLAGS / CXXFLAGS-Umgebungsvariable gesetzt (und exportiert) hast (zum Beispiel in der ~/.profile bzw. global in der /etc/profile), überschreibt diese die vom Programmautor vorgesehenen CFLAGS / CXXFLAGS in den Makefiles / configure-Scripts.
Wenn du ganz sicher gehen willst, kannst du auch die make-Option '-e' beim make-Vorgang verwenden, was make strikt anweist, Umgebungsvariablen gegenüber in den Makefiles gesetzten Variablen vorzuziehen.
Allerdings ist diese ganze Optimierungs-Geschichte nicht immer unkritisch. Zahlreiche Optimierung funktionieren mit diversen Programmen nicht. Vor allem bei '-ffast-math' darfst du dich nicht darauf verlassen - hier heisst es ausprobieren, und darauf gefasst sein, dass das Erzeugte Binary beim ersten Test sofort segfaultet - bzw. sich freuen, falls das nicht der Fall ist.
Andere Programme, die nicht auf autoconf sondern nur auf simple Makefiles setzen, definieren häufig in den CFLAGS / CXXFLAGS-Variablen gcc-Parameter wie -I (Suchpfad für Includes um Verzeichnis XYZ erweitern), um lokale (zum Programm gehörende Headers) beim Compilierungsvorgang zugängig zu machen, wenn diese sich nicht im Verzeichnis der zu Compilierenden Sourcefile befinden oder mit <> statt "" included wurden.
Nenn es von mir aus schlechtes Design, dass Programmierer
"-I../anydir"
zu den CFLAGS in einer Makefile hinzufügen anstatt an entsprechender Stelle beim Compileraufruf
$(CFLAGS) -I../anydir
zu verwenden, Fakt ist aber, dass es gängige Praxis ist.
Hier würde also ein Überschreiben der CFLAGS durch die Umgebungsvariable $CFLAGS dazu führen, dass die betreffende Applikation / Library nicht compiliert !
Teilweise ist es von daher sogar besser besser, die Umgebunsvariable $CC (zu verwendener Compiler) auf
gcc [gewünschte Optimierungsflags]
zu setzen, weil dies nicht irgendwelche Makefile-Strukturen beeinflusst, in denen Includedirs in die CFLAGS "hargecodet" sind.
Aber wenn du meine Meinung zu dem ganzen Thema wissen willst:
Durch entsprechende Compileroptimierung erlangst du im Durchschnitt maximal 3 - 5 % mehr Performace. Selbstverständlich gibt es Extrembeispiele, aber ich rede jetzt vom Durchschnitt ...
Und wirklich profitierst du nur davon wenn du dein *komplettes* System optimierst, und selbst dann hast du nur 3 - 5 % mehr Gesamtperformace für viele Stunden / Tage Compilierarbeit.
Optimierungen wie "-ffast-math" sind zudem (wie oben schon einmal von mir angesprochen) sehr kritisch. Wenn du alle deine Applikationen mit "-ffast-math" Optimierst, wirst du sicher früher oder später über einige stoßen, bei denen die Optimierung zu einem nicht funktionsfähigen Binary führt. Und nicht funktionsfähig muss aber nicht heissen, dass das Binary insgesamt nicht funktioniert, d.h. schon beim Start abstürzt, sondern kann auch bedeuten, dass nur eine bestimmte Routine crashen wird. Tja, und wie willst du das auf einfache Art und Weise heraus finden ? Du schaffst dir quasi selber Probleme, die du evtl. später für Bugs in Applikationen oder Library hältst ...
Die Programmierer wissen in der Regel schon, welche Optimierungen sie für ihren Quelltext verwenden können, damit mit möglichst vielen verschiedenen Compilerversionen funktionierender Code erzeugt wird, und setzen die CFLAGS auch entsprechend. Und da jetzt zwischenzufuchteln und mit den eigenen Optimierungsflags zu kommen ist schon kritisch.
Niemand verbietet dir zu optimieren, ich will dich auch nicht davon abhalten (versteh das jetzt bitte nicht falsch).
Nur ich wäre etwas vorsichtiger mit allem über "-O2", -fexpensive-optimizations und insbesondere -ffast-math - vor allem bei älteren Compilerversionen. Zudem halte ich es für schlecht, die CFLAGS global als Umgebungsvariable zu setzen, d.h. für alle Programme die selben, u.U. kritischen Optimierungsoptionen zu verwenden (und wegen einiger schlecht designeten Makefiles - s.o.).
Vielmehr sollte man mal ein Blick in die Makefiles der einzelnen Programme schauen, gucken, wie der Programmierer optimieren möchte (d.h. wie er die CFLAGS gesetzt hat), und dann evtl. mal ein '-O'-Level erhöhen und die Applikation später ausgiebig testen. Insbesondere ältere Applikationen, bei denen das letzte Release auf 1996 - 1998 gedatet ist, verwenden häufig noch ein einfaches "-O", weil damals die Compiler noch nicht so ausgereift waren und ein "-O2" viel kritischer war. In solchen Fällen ist es meistens unproblematisch, mit einer modernen Compilerversion das "-O" durch ein "-O2" zu ersetzen ... das ist harmlos.
Aber ein Programm, dass man nicht selbst geschrieben hat, Partout mit "-O3 -fexpensive-optimizations -ffst-math" compilieren zu wollen ist aber etwas ganz anderes !
Insgesamt ist es auch ziemlich viel Aufwand für ... sagen wir mal, ziemlich wenig Gewinn.
Außerdem:
Wenn die Leute die Zeit, die sie in Compilierer-Optimierung gesteckt haben (einschließlich der Zeit die wir jetzt hier für unsere Diskussion verbrauchen) in andere Sachen gesteckt hätten, die zu mehr Systemperformance beitragen (Arbeit am Kernel und anderer essentieller Software, Aufbau einer HD & Controller-Capability-Database für hdparm), wären unsere Linux-Systeme jetzt auch ohne Compiler-Optimierung deutlich schneller als sie jetzt sind ...
> Nenn es von mir aus schlechtes Design, dass Programmierer > > "-I../anydir" > > zu den CFLAGS in einer Makefile hinzufügen anstatt an entsprechender Stelle beim Compileraufruf > > $(CFLAGS) -I../anydir > > zu verwenden, Fakt ist aber, dass es gängige Praxis ist.
Nein; zumindest in der GNU Welt ist es ein Fehler:
---- standard.info/Command Variables ---- If there are C compiler options that _must_ be used for proper compilation of certain files, do not include them in `CFLAGS'. Users expect to be able to specify `CFLAGS' freely themselves. -----------------------------------------
Bei automake gibt es die INCLUDE Variable, die fuer soetwas geeignet ist:
-------- automake.info/Program variables ---- `INCLUDES' A list of `-I' options. This can be set in your `Makefile.am' if you have special directories you want to look in. ... `INCLUDES' can actually be used for other `cpp' options besides `-I'. ---------------------------------------------
Bei Programmen, wo man eine missbraeuchliche Verwendung von CFLAGS feststellt, sollte man evtl. einen Bugreport schreiben.
"-mpentiumpro" bedeutet nur, dass der GCC diverse Sachen so arrangiert, dass sie auf einem Pentium Pro (oder darüber) am schnellsten / optimalsten laufen. Das erzeugte Binary läuft aber immer noch auf einem normalen Pentium (dort natürlich nicht so gut, da diverse Sachen für den PPro optimiert wurden), oder von mir aus auch auf einem 386er, ist also *nicht* "Pentium Pro and above"-abhängig, aber trotzdem für "Pentium Pro and above" optimiert.
Erst durch das "-march=pentiumpro" (oder "-march=i686") wird Code für den spezifischen Prozessor erzeugt (hier: Pentium Pro), der dann auch wirklich nicht mehr auf einem kleineren Prozessor läuft, also in unserem Beispiel einen Pentium Pro oder höher vorraus setzt.
Wenn ich mich da geirrt habe, korrigiert mich bitte.
Assume the defaults for the machine type CPU TYPE when scheduling instructions.
[...]
While picking a specific CPU TYPE will schedule things appropriately for that particular chip, the compiler will NOT generate any code that does not run on the i386 without the '-march=CPU TYPE' option being used.
> > reicht > > > > rpm --rebuild file.src.rpm -target=i686 > > > > um einen optimalen code für meinen intelp3 850 zu erstellen??? > > > Manche SPRMs haben das schon eingebaut, die meisten aber nicht.
Naja; die meisten RPMS von RH >=7 verwenden ein %configure Makro, was gaengige ..FLAGS setzt.
also, ich muss nochmal was sagen zu diesem optionen. bei mir gibts damit keinerlei stabilitätsprobleme. mein komplettes gnome, galeon und mozilla hab ich damit kompiliert. galeon 0.11 + moz 0.9.1 laufen damit schnell und stable as hell
>Für C++-Programme lautet er CXXFLAGS, manchmal CPPFLAGS.
CPPFLAGS ist etwas anderes als CXXFLAGS !
CXXFLAGS sind die Flags für den C++-Compiler, analog zu CFLAGS für den C-Compiler.
CPPFLAGS sind aber die Flags für den C-PreProzessor (CPP) !
Da man den heute selten getrennt aufruft, landen die Optimierungsflags am Ende trotzdem im GCC-Aufruf ... aber falsch ist es trotzdem. Und wenn ein Programm ihn denn sogar getrennt aufruft, wird dieser Aufruf fehlschlagen, da der cpp garantiert kein -O2, -ffast-math & co. kennt :-).
Wer noch mehr optimieren möchte, sollte mal den pgcc probieren(www.goof.com), der hat nämlich -O6(!). Andererseits sollte man eher mal den zu optimierenden Code durchchecken und eine Laufzeitanalyse starten (O(n)), was bringt es ein Algorithmus mit einer Laufzeit O(n^2) mit -O6 zu compilieren, wenn es auch einen Algorithmus mit Laufzeit O(n log n)gibt, der ist auch ohne compiler-opti's schneller. Es gibt also noch viel zu tun...
Aber... vielleicht sollten wir auch warten, bis Intel ihren x86-Compiler (v-tune o.ä.) endlich für Linux anbieten, der erzeugt immer optimalen Code, aber startet dieses Teil nur nachts, der braucht nämlich ewig.
das "-O3 --ffast-math" evtl. kritisch sein kann hab ich kapiert aber was ist mit "-m486 -mcpu=i686 -march=i686"? Das müsste doch meinen Duron auf Trab bringen oder?
Macht die Binaries dann halt nur von einem Pentium Pro oder höher ab, d.h. sie würden so nicht mehr auf deinem altern 486er laufen.
Aber -march=i686 (oder -march=pentiumpro) reicht, denn das -march=i686 beinhaltet bereits das -mcpu=i686, und -mpentiumpro ist nur ein Alias für -mcpu=i686.
Jetzt sind eine Menge von Dateien entstanden; u.a. ./configure, was -- inkl. des darauffolgenden `makes' -- aufgerufen werden kann:
$ ./configure ... creating Makefile
$ make c++ -DPACKAGE=\"test\" -DVERSION=\"0.1\" -I. -I. -g -O2 -c test.cc c++ -g -O2 -o test test.o $
(man beachte das `-g -O2'!)
Probieren wir es jetzt mal mit gesetzten CXXFLAGS:
$ make clean $ CXXFLAGS='-march=i686' ./configure $ make c++ -DPACKAGE=\"test\" -DVERSION=\"0.1\" -I. -I. -march=i686 -c test.cc c++ -march=i686 -o test test.o $
Jetzt ist dort, wo frueher `-g -O2' stand, `-march=i686' gesetzt.
neben dem pgcc gibt es auch einen agcc (für amdŽs). wer wirklich optimieren will, sollte die finger von -03 oder ähnlichem lassen und lieber auf den pgcc oder agcc umsteigen und dann mit höchstends -02 optimieren. der performance gewinn ist beachtlich und bei -02 gibts auch keine probs wegen falsch erzeugtem code, segmentation-faults usw. ein z.b. komplett mit dem pgcc optimiertes system läuft jedem anderen vergleichbaren gcc-system davon ;)
>ein z.b. komplett mit dem pgcc optimiertes >system läuft jedem anderen vergleichbaren >gcc-system davon
Mit der Äußerung wäre ich vorsichtig.
Einige Applikationen, die viel mit komplexen Berechnungen zu tun haben (Komprimierungsprogramme zum Beispiel) werden vielleicht merklich schneller laufen, aber *insgesamt* dürfte der Performancegewinn gegenüber einem mit gleichen Flags, aber einem ungepatchten gcc compilierten System wirklich höchstens bei 5 % liegen.
In sofern gibt es bessere und effizientere Methoden, mehr Gesamtperformance zu erlangen.
Trotzdem ... wo mehr Performance rauszuholen ist, warum nicht die Möglichkeiten nutzen ? Wer die Zeit und die Lust hat, oder sowieso alles selber compiliert (LFS-System) den möchte ich nicht vom pgcc / agcc abhalten.
Vernünftiger als "gefährliche" CFLAGS ist das auf jeden Fall.
gerade unter linux, wo sehr häufig scriptbasiertes tools (awk, perl, usw.) laufen ist die performance mit dem pgcc bedeutend höher. ein vergleichstest (fibonacci-berechung mit perl, awk, ruby)liefert einen performance gewinn von über 60% - wohl gemerkt bei einem lfs-system komplett mit dem pgcc gebaut. bei "normalen" anwendungen liegt der gewinn in der tat vielleicht bei 5-10% bei "sanfter" optimierung (-O2 -ffast-math -fno-frame-pointer +pentium-flags). bessere performance und trotzdem keine seg-faults - das ist ein guter deal der für den pgcc/agcc spricht
Nichs desto trotz bin ich (auch begeisterter pgcc-Compilierer :-)) immer noch der Ansicht, dass wir weiter wären (und dein System viel schneller wäre), wenn die Energie, die in pgcc gesteckt wurde (und die Zeit in der sich Leute über Compiler-Optimierung Gedanken gemacht haben) in die Verbesserung der Performace von Kernel, Treibern und essentieller Software gesteckt worden wäre.
stimmt schon, idealweise sollte das ganze paket stimmen - also hochperformanter kernel, treiber usw. und der "rest" über hochentwickelte build-tools. aber das ist nunmal ein ideal dem wir alle hinterherjagen aber wie es halt so mit idealen ist, erreicht werden sie fast nie...
Sind denn die (meisten) Optimierungen, die PGCC und agcc vornehmen auch im kommenden gcc 3.0 enthalten? Ein mit gcc 3.0 snapshot kompiliertes bzip2 hat nämlich einen nur sehr geringen Geschwindigkeitsvorteil gegenüber gcc2.95 gehabt.
meines wissens nein! der kommende 3.0 enthält keine pentium oder amd optimierung. es wird bei erscheinen wieder angepasste patches geben um den standard-gcc die entsprechenden optimierungen beizubringen.
die pgcc/agcc patches sind separate projekte und gehören nicht zum gcc-projekt. im grunde wäre es aber denkbar diese speziellen projekte in den gcc-projekt baum zu integrieren.
Ersetze Windows-Welt durch Unix-Welt, dann wird's richtiger. Vielleicht sollte man aber eher sagen: die Welt der High-End RISC-Prozessoren.
Früher galt gcc als der beste Compiler, oft besser als die von den UNIX-Herstellern gelieferten Compiler. Doch der Vorsprung ist verlorengegangen. Heutige CPUs sind so komplex, daß im Prinzip nur der Hersteller weiß, wie man den Code am besten optimiert.
Klasse, also erstmal danke an alle wie das mit dem gcc und dem Optimieren ist wollte ich schon immer wissen.
Jetzt habe ich aber noch eine Frage.
Ist es möglich den gcc und den agcc gleichzeitig installiert zu haben um wählen zu können welcher compilier gerade verwendet werden soll?
Wenn ja wie mache ich das, bzw. wie gebe ich das an? Beim starten von ./configure?
Grund ist nämlich der, als Client maschine habe ich einen Athlon, also wäre der agcc compiler wirklich von vorteil. Die sache hat nur einen Haken, manchmal muß ich auch für meinen alten intel 486 Programme compilieren wo ich natürlich grundsätzlich meinen schnelleren Athlon dazu verwende.
Am einfachsten ist es, den agcc einfach an einen komplett anderen Prefix zu installieren (beispielsweise /usr/local/agcc), und dann in /usr/local/bin ein
ln -s ../agcc/bin/gcc agcc
zu machen. Nun setzt du, falls du den agcc benutzen möchtest, einfach die Umgebungsvariable $CC auf "agcc", bzw. rufst das configure-Script in der Form
Das ist nicht auf die Windowswelt beschränkt. Es gibt auch kommerzielle Compiler für Linux die besseren/optimierteren Code erzeugen. Ist ja eigentlich auch logisch das das vom Betriebssystem unabhängig ist, der Code wird ja auf den Prozessor zugeschnitten.
Ja, diese kommerziellen Compilier gibt es - leider ist aber der Großteil der Software nur für das Compilieren mit dem gcc ausgelegt.
Versuch mal den Kernel oder die glibc mit einem anderen Compilier als dem gcc und dessen Varianten zu übersetzen - es wird dir nicht gelingen, weil diese Projekte so viel "gcc-Magie" benutzen und teilweise sogar auf gcc-Bugs aufbauen, dass mit jedem anderen Compiler (auch wenn er noch so schnellen Code erzeugt) nichts brauchbares heraus kommt.
Hallo das war mir eigentlich schon bekannt, nur gerade fällt mir beim Kernelcompilieren auf, das der nur "-O2" verwendet! Das finde ich nämlich nicht lustig wenn ich das alles nochmal machen darf!
Ist das nur bei SuSE so oder ist das distributionsübergreifend?
Beim Kernel würde ich nichts an den CFLAGS rumfummeln.
Im Kernel steckt so viel gcc-Magie ... wenn da an irgend einer Stelle etwas ungewollt "wegoptimiert" wird, läuft der Kernel höchstwahrscheinlich nachher nicht.
Pubert
-O300
Euer gcc wird es akzeptieren ...
Selbstverständlich gibt es keine 300 Optimierungsstufen !
Soweit ich informiert bin ist die höchste Optimierungsstufe zur Zeit wirklich -O3 (mal abgesehen von -Os - Optimierung auf Größe), alles darüber wird *zur Zeit* wie -O3 behandelt.
Einige Programme benutzen lediglich -O6 & co., weil sie annehmen, dass zukünftige GCC-Versionen entsprechend hohe Optimierungsstufen anbieten und dann auch von den starken Optimierungen profitieren wollen.
Wenn du die CFLAGS / CXXFLAGS-Umgebungsvariable gesetzt (und exportiert) hast (zum Beispiel in der ~/.profile bzw. global in der /etc/profile), überschreibt diese die vom Programmautor vorgesehenen CFLAGS / CXXFLAGS in den Makefiles / configure-Scripts.
Wenn du ganz sicher gehen willst, kannst du auch die make-Option '-e' beim make-Vorgang verwenden, was make strikt anweist, Umgebungsvariablen gegenüber in den Makefiles gesetzten Variablen vorzuziehen.
Allerdings ist diese ganze Optimierungs-Geschichte nicht immer unkritisch.
Zahlreiche Optimierung funktionieren mit diversen Programmen nicht. Vor allem bei '-ffast-math' darfst du dich nicht darauf verlassen - hier heisst es ausprobieren, und darauf gefasst sein, dass das Erzeugte Binary beim ersten Test sofort segfaultet - bzw. sich freuen, falls das nicht der Fall ist.
Andere Programme, die nicht auf autoconf sondern nur auf simple Makefiles setzen, definieren häufig in den CFLAGS / CXXFLAGS-Variablen gcc-Parameter wie -I (Suchpfad für Includes um Verzeichnis XYZ erweitern), um lokale (zum Programm gehörende Headers) beim Compilierungsvorgang zugängig zu machen, wenn diese sich nicht im Verzeichnis der zu Compilierenden Sourcefile befinden oder mit <> statt "" included wurden.
Nenn es von mir aus schlechtes Design, dass Programmierer
"-I../anydir"
zu den CFLAGS in einer Makefile hinzufügen anstatt an entsprechender Stelle beim Compileraufruf
$(CFLAGS) -I../anydir
zu verwenden, Fakt ist aber, dass es gängige Praxis ist.
Hier würde also ein Überschreiben der CFLAGS durch die Umgebungsvariable $CFLAGS dazu führen, dass die betreffende Applikation / Library nicht compiliert !
Teilweise ist es von daher sogar besser besser, die Umgebunsvariable $CC (zu verwendener Compiler) auf
gcc [gewünschte Optimierungsflags]
zu setzen, weil dies nicht irgendwelche Makefile-Strukturen beeinflusst, in denen Includedirs in die CFLAGS "hargecodet" sind.
Aber wenn du meine Meinung zu dem ganzen Thema wissen willst:
Durch entsprechende Compileroptimierung erlangst du im Durchschnitt maximal 3 - 5 % mehr Performace.
Selbstverständlich gibt es Extrembeispiele, aber ich rede jetzt vom Durchschnitt ...
Und wirklich profitierst du nur davon wenn du dein *komplettes* System optimierst, und selbst dann hast du nur 3 - 5 % mehr Gesamtperformace für viele Stunden / Tage Compilierarbeit.
Optimierungen wie "-ffast-math" sind zudem (wie oben schon einmal von mir angesprochen) sehr kritisch.
Wenn du alle deine Applikationen mit "-ffast-math" Optimierst, wirst du sicher früher oder später über einige stoßen, bei denen die Optimierung zu einem nicht funktionsfähigen Binary führt.
Und nicht funktionsfähig muss aber nicht heissen, dass das Binary insgesamt nicht funktioniert, d.h. schon beim Start abstürzt, sondern kann auch bedeuten, dass nur eine bestimmte Routine crashen wird.
Tja, und wie willst du das auf einfache Art und Weise heraus finden ? Du schaffst dir quasi selber Probleme, die du evtl. später für Bugs in Applikationen oder Library hältst ...
Die Programmierer wissen in der Regel schon, welche Optimierungen sie für ihren Quelltext verwenden können, damit mit möglichst vielen verschiedenen Compilerversionen funktionierender Code erzeugt wird, und setzen die CFLAGS auch entsprechend.
Und da jetzt zwischenzufuchteln und mit den eigenen Optimierungsflags zu kommen ist schon kritisch.
Niemand verbietet dir zu optimieren, ich will dich auch nicht davon abhalten (versteh das jetzt bitte nicht falsch).
Nur ich wäre etwas vorsichtiger mit allem über "-O2", -fexpensive-optimizations und insbesondere -ffast-math - vor allem bei älteren Compilerversionen.
Zudem halte ich es für schlecht, die CFLAGS global als Umgebungsvariable zu setzen, d.h. für alle Programme die selben, u.U. kritischen Optimierungsoptionen zu verwenden (und wegen einiger schlecht designeten Makefiles - s.o.).
Vielmehr sollte man mal ein Blick in die Makefiles der einzelnen Programme schauen, gucken, wie der Programmierer optimieren möchte (d.h. wie er die CFLAGS gesetzt hat), und dann evtl. mal ein '-O'-Level erhöhen und die Applikation später ausgiebig testen.
Insbesondere ältere Applikationen, bei denen das letzte Release auf 1996 - 1998 gedatet ist, verwenden häufig noch ein einfaches "-O", weil damals die Compiler noch nicht so ausgereift waren und ein "-O2" viel kritischer war.
In solchen Fällen ist es meistens unproblematisch, mit einer modernen Compilerversion das "-O" durch ein "-O2" zu ersetzen ... das ist harmlos.
Aber ein Programm, dass man nicht selbst geschrieben hat, Partout mit "-O3 -fexpensive-optimizations -ffst-math" compilieren zu wollen ist aber etwas ganz anderes !
Insgesamt ist es auch ziemlich viel Aufwand für ... sagen wir mal, ziemlich wenig Gewinn.
Außerdem:
Wenn die Leute die Zeit, die sie in Compilierer-Optimierung gesteckt haben (einschließlich der Zeit die wir jetzt hier für unsere Diskussion verbrauchen) in andere Sachen gesteckt hätten, die zu mehr Systemperformance beitragen (Arbeit am Kernel und anderer essentieller Software, Aufbau einer HD & Controller-Capability-Database für hdparm), wären unsere Linux-Systeme jetzt auch ohne Compiler-Optimierung deutlich schneller als sie jetzt sind ...
>
> "-I../anydir"
>
> zu den CFLAGS in einer Makefile hinzufügen anstatt an entsprechender Stelle beim Compileraufruf
>
> $(CFLAGS) -I../anydir
>
> zu verwenden, Fakt ist aber, dass es gängige Praxis ist.
Nein; zumindest in der GNU Welt ist es ein Fehler:
---- standard.info/Command Variables ----
If there are C compiler options that _must_ be used for proper
compilation of certain files, do not include them in `CFLAGS'. Users
expect to be able to specify `CFLAGS' freely themselves.
-----------------------------------------
Bei automake gibt es die INCLUDE Variable, die fuer soetwas geeignet ist:
-------- automake.info/Program variables ----
`INCLUDES'
A list of `-I' options. This can be set in your `Makefile.am' if
you have special directories you want to look in.
...
`INCLUDES' can actually be used for other `cpp' options besides
`-I'.
---------------------------------------------
Bei Programmen, wo man eine missbraeuchliche Verwendung von CFLAGS feststellt, sollte man evtl. einen Bugreport schreiben.
Stop.
Soweit ich weis ist das nicht korrekt.
"-mpentiumpro" bedeutet nur, dass der GCC diverse Sachen so arrangiert, dass sie auf einem Pentium Pro (oder darüber) am schnellsten / optimalsten laufen.
Das erzeugte Binary läuft aber immer noch auf einem normalen Pentium (dort natürlich nicht so gut, da diverse Sachen für den PPro optimiert wurden), oder von mir aus auch auf einem 386er, ist also *nicht* "Pentium Pro and above"-abhängig, aber trotzdem für "Pentium Pro and above" optimiert.
Erst durch das "-march=pentiumpro" (oder "-march=i686") wird Code für den spezifischen Prozessor erzeugt (hier: Pentium Pro), der dann auch wirklich nicht mehr auf einem kleineren Prozessor läuft, also in unserem Beispiel einen Pentium Pro oder höher vorraus setzt.
Wenn ich mich da geirrt habe, korrigiert mich bitte.
`-mcpu=CPU TYPE'
Assume the defaults for the machine type CPU TYPE when scheduling instructions.
[...]
While picking a specific CPU TYPE will schedule things appropriately for that particular chip, the compiler will NOT generate any code that does not run on the i386 without the '-march=CPU TYPE' option being used.
reicht
rpm --rebuild file.src.rpm -target=i686
um einen optimalen code für meinen intelp3 850 zu erstellen???
Jedes SRPM hat ein sogenanntes Spec-File. Das Target wird darin abgefragt und verschiedene Optionen werden entsprechend anbepasst.
Das braucht man z.B. wenn man für einen Intel oder eine Alpha compilieren will.
Manche SPRMs haben das schon eingebaut, die meisten aber nicht.
> >
> > rpm --rebuild file.src.rpm -target=i686
> >
> > um einen optimalen code für meinen intelp3 850 zu erstellen???
> >
> Manche SPRMs haben das schon eingebaut, die meisten aber nicht.
Naja; die meisten RPMS von RH >=7 verwenden ein %configure Makro, was gaengige ..FLAGS setzt.
Diese sind per Default dann `-march='
1. rpm -U blablah.src.rpm
2. xemacs /usr/src/redhat/SPECS/blablah.spec
3. rpm -b[asb] /usr/src/redhat/SPECS/blablah.spec
Fuer weiteres hilft die (spaerliche) rpm(8) Manpage weiter, das RPM-HOWTO, und/oder Maximum-RPM.
danke
-O3 -march=k6 -mcou=k6 -fstrict-aliasing -funroll-loops -ffast-math
das ergibt bei mir den schnellstmöglichen code, getestet nbench-byte :)
ps
-mieee-fp ist bei -O3 schon eingeschaltet, jedebfalls bei gcc 2.95.x
das -mpentiumpro sollte ebenfalls überflüssig sein..
Ist es auch (soweit ich weis).
-march=[XYZ] beinhaltet bereits -m[XYZ], und -mcpu=[XYZ] ist nur ein alias für -m[XYZ].
>Für C++-Programme lautet er CXXFLAGS, manchmal CPPFLAGS.
CPPFLAGS ist etwas anderes als CXXFLAGS !
CXXFLAGS sind die Flags für den C++-Compiler, analog zu CFLAGS für den C-Compiler.
CPPFLAGS sind aber die Flags für den C-PreProzessor (CPP) !
Da man den heute selten getrennt aufruft, landen die Optimierungsflags am Ende trotzdem im GCC-Aufruf ... aber falsch ist es trotzdem.
Und wenn ein Programm ihn denn sogar getrennt aufruft, wird dieser Aufruf fehlschlagen, da der cpp garantiert kein -O2, -ffast-math & co. kennt :-).
Aber... vielleicht sollten wir auch warten, bis Intel ihren x86-Compiler (v-tune o.ä.) endlich für Linux anbieten, der erzeugt immer optimalen Code, aber startet dieses Teil nur nachts, der braucht nämlich ewig.
In diesem Sinne...
Oder mein md5sum ist im Arsch :-).
das "-O3 --ffast-math" evtl. kritisch sein kann hab ich kapiert aber was ist mit "-m486 -mcpu=i686 -march=i686"? Das müsste doch meinen Duron auf Trab bringen oder?
bye
/ Bernd /
Macht die Binaries dann halt nur von einem Pentium Pro oder höher ab, d.h. sie würden so nicht mehr auf deinem altern 486er laufen.
Aber -march=i686 (oder -march=pentiumpro) reicht, denn das -march=i686 beinhaltet bereits das -mcpu=i686, und -mpentiumpro ist nur ein Alias für -mcpu=i686.
Der Entwickler gar nicht. Er sollte nur ein den Standards genuegendes configure.in Script + Makefile.am's schreiben.
Den Rest erledigt automake+autoconf+libtool von ganz allein...
2. make
3. make [DESTDIR=...] install
configure, makefile oder was??
cya
Wir beginnen mit einem minimalen Beispielprojekt 'test', wo es 3
Dateien gibt:
---- Makefile.am ------
bin_PROGRAMS = test
test_SOURCES = test.cc
---- configure.in ------
AC_INIT(test.cc)
AM_INIT_AUTOMAKE(test,0.1)
AC_PROG_AWK
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_CXX
AC_OUTPUT(Makefile)
---- test.cc -------
int main() {}
Jetzt werden noetige Dateien erzeugt (`$' steht fuer den Shellinput):
-----------------------
$ automake --foreign -a
automake: configure.in: installing `./install-sh'
automake: configure.in: installing `./mkinstalldirs'
automake: configure.in: installing `./missing'
$ aclocal
$ autoconf
$
-----------------------
Jetzt sind eine Menge von Dateien entstanden; u.a. ./configure, was --
inkl. des darauffolgenden `makes' -- aufgerufen werden kann:
$ ./configure
...
creating Makefile
$ make
c++ -DPACKAGE=\"test\" -DVERSION=\"0.1\" -I. -I. -g -O2 -c test.cc
c++ -g -O2 -o test test.o
$
(man beachte das `-g -O2'!)
Probieren wir es jetzt mal mit gesetzten CXXFLAGS:
$ make clean
$ CXXFLAGS='-march=i686' ./configure
$ make
c++ -DPACKAGE=\"test\" -DVERSION=\"0.1\" -I. -I. -march=i686 -c test.cc
c++ -march=i686 -o test test.o
$
Jetzt ist dort, wo frueher `-g -O2' stand, `-march=i686' gesetzt.
Alle Klarheiten beseitigt?
ein z.b. komplett mit dem pgcc optimiertes system läuft jedem anderen vergleichbaren gcc-system davon ;)
>system läuft jedem anderen vergleichbaren
>gcc-system davon
Mit der Äußerung wäre ich vorsichtig.
Einige Applikationen, die viel mit komplexen Berechnungen zu tun haben (Komprimierungsprogramme zum Beispiel) werden vielleicht merklich schneller laufen, aber *insgesamt* dürfte der Performancegewinn gegenüber einem mit gleichen Flags, aber einem ungepatchten gcc compilierten System wirklich höchstens bei 5 % liegen.
In sofern gibt es bessere und effizientere Methoden, mehr Gesamtperformance zu erlangen.
Trotzdem ... wo mehr Performance rauszuholen ist, warum nicht die Möglichkeiten nutzen ?
Wer die Zeit und die Lust hat, oder sowieso alles selber compiliert (LFS-System) den möchte ich nicht vom pgcc / agcc abhalten.
Vernünftiger als "gefährliche" CFLAGS ist das auf jeden Fall.
bei "normalen" anwendungen liegt der gewinn in der tat vielleicht bei 5-10% bei "sanfter" optimierung (-O2 -ffast-math -fno-frame-pointer +pentium-flags). bessere performance und trotzdem keine seg-faults - das ist ein guter deal der für den pgcc/agcc spricht
Nichs desto trotz bin ich (auch begeisterter pgcc-Compilierer :-)) immer noch der Ansicht, dass wir weiter wären (und dein System viel schneller wäre), wenn die Energie, die in pgcc gesteckt wurde (und die Zeit in der sich Leute über Compiler-Optimierung Gedanken gemacht haben) in die Verbesserung der Performace von Kernel, Treibern und essentieller Software gesteckt worden wäre.
Aber gut ... das ist eine andere Geschichte.
die pgcc/agcc patches sind separate projekte und gehören nicht zum gcc-projekt. im grunde wäre es aber denkbar diese speziellen projekte in den gcc-projekt baum zu integrieren.
Die Umgebungsvariable $CFLAGS überschreibt die im configure-Script vorgesehenen CFLAGS.
Wie oben schon einmal erwähnt kannst du also ein
CFLAGS=[bevorzugte Flags] ./configure [Optionen]
machen.
Die erstellten Makefiles beeinhalten dann schon die von dir definierten CFLAGS, von daher ist nur noch ein
make
nötig um die jeweilige Applikation / Library mit den gewünschen Flags zu übersetzen.
Ich möchte nichts gegen den Gcc sagen, von der optimierung abgesehen ein super Compiler
Früher galt gcc als der beste Compiler, oft besser als die von den UNIX-Herstellern gelieferten Compiler. Doch der Vorsprung ist verlorengegangen. Heutige CPUs sind so komplex, daß im Prinzip nur der Hersteller weiß, wie man den Code am besten optimiert.
Jetzt habe ich aber noch eine Frage.
Ist es möglich den gcc und den agcc gleichzeitig installiert zu haben um wählen
zu können welcher compilier gerade verwendet werden soll?
Wenn ja wie mache ich das, bzw. wie gebe ich das an? Beim starten von ./configure?
Grund ist nämlich der, als Client maschine habe ich einen Athlon, also wäre der agcc compiler wirklich von vorteil.
Die sache hat nur einen Haken, manchmal muß ich auch für meinen alten intel 486 Programme compilieren wo ich natürlich grundsätzlich
meinen schnelleren Athlon dazu verwende.
Am einfachsten ist es, den agcc einfach an einen komplett anderen Prefix zu installieren (beispielsweise /usr/local/agcc), und dann in /usr/local/bin ein
ln -s ../agcc/bin/gcc agcc
zu machen.
Nun setzt du, falls du den agcc benutzen möchtest, einfach die Umgebungsvariable $CC auf "agcc", bzw. rufst das configure-Script in der Form
CC=agcc ./configure
auf.
Ist ja eigentlich auch logisch das das vom Betriebssystem unabhängig ist, der Code wird ja auf den Prozessor zugeschnitten.
Versuch mal den Kernel oder die glibc mit einem anderen Compilier als dem gcc und dessen Varianten zu übersetzen - es wird dir nicht gelingen, weil diese Projekte so viel "gcc-Magie" benutzen und teilweise sogar auf gcc-Bugs aufbauen, dass mit jedem anderen Compiler (auch wenn er noch so schnellen Code erzeugt) nichts brauchbares heraus kommt.
das war mir eigentlich schon bekannt, nur gerade fällt mir beim Kernelcompilieren auf, das der nur "-O2" verwendet!
Das finde ich nämlich nicht lustig wenn ich das alles nochmal machen darf!
Ist das nur bei SuSE so oder ist das distributionsübergreifend?
MfG
Daniel
Im Kernel steckt so viel gcc-Magie ... wenn da an irgend einer Stelle etwas ungewollt "wegoptimiert" wird, läuft der Kernel höchstwahrscheinlich nachher nicht.