# allg. Frage: Compiler und Optimierung

## FrancisA

Man hört ja immer wieder, man soll nicht allzu aggressiv optimieren (zb -O3). Ich verstehe nicht ganz, warum ein code dann nicht mehr funktionieren soll. Naiv stelle ich mir vor, dass der Compiler keinen Code erstellen darf, der nicht sicher ausgeführt wird. Weil wie soll man dann wissen, ob die größte Optimierung (wenn nicht durch ausprobieren) geht? Oder kann man sagen, zb -O2 optimiert auch noch recht gut, und es funktioniert der kompilierte Code auch noch sicher?

----------

## aleph-muc

Hallo FrancisA,

das Problem ist nicht, dass sich der kompilierte Code nicht ausführen läßt, sondern dass sich der Code mit zu aggressiven Flags nicht kompilieren läßt.

Grüße

aleph

----------

## FrancisA

 *aleph-muc wrote:*   

> Hallo FrancisA,
> 
> das Problem ist nicht, dass sich der kompilierte Code nicht ausführen läßt, sondern dass sich der Code mit zu aggressiven Flags nicht kompilieren läßt.
> 
> Grüße
> ...

 

Ach so, danke für die Erklärung. Das habe ich gerade andersherum aufgefasst gehabt.

----------

## franzf

Es kann sehr wohl Crashes oder komisches Verhalten zur Laufzeit geben, wenn man unbedacht Flags setzt. Die Safe CFLAGS sollten für den Anfang reichen. An Optimierung solltest du nur denken, wenn du weißt was du machst  :Smile:  (ich weiß es nicht, und es interessiert mich auch nicht, drum mach ich es nicht)

----------

## Josef.95

Nutze evtl. auch die idR sehr gute Gentoo Dokumentationen, zb Kompilations-Optimierungs-Leitfaden  :Wink: 

----------

## FrancisA

 *Josef.95 wrote:*   

> Nutze evtl. auch die idR sehr gute Gentoo Dokumentationen, zb Kompilations-Optimierungs-Leitfaden 

 

Ja, also ich glaube (nachdem was ich bis jetzt gelesen habe), dass der richtige Prozessortyp einmal wichtiger ist, und dass -O2 die Standard Optimierung ist, die man auch lassen sollte. -O3 macht dann oft den Code noch größer und dadurch nicht unbedingt schneller. Da kommt es wahrscheinlich mehr auf die Implementierung selbst an. Was bringt zb 5% (oder was weiß ich) schnellerer Code. Da ist die Frage: steht der Aufwand dafür?

----------

## Josef.95

 *FrancisA wrote:*   

> Ja, also ich glaube (nachdem was ich bis jetzt gelesen habe), dass der richtige Prozessortyp einmal wichtiger ist, und dass -O2 die Standard Optimierung ist, die man auch lassen sollte. -O3 macht dann oft den Code noch größer und dadurch nicht unbedingt schneller.

 

Ja, ich denke das man mit der Auswahl der zum Prozessortyp passenden -march schon nahezu bestmögliches getan hat. Und ja,  -O3 systemweit zu verwenden davon wird ab gcc 4.x auch schon im genannten Optimierungs-Leitfaden  abgeraten.

Doch den Prozessortyp und die dazu passende -march ist ja bei manchen exotischen Prozessoren gar nicht so leicht zu ermitteln, wie zb bei einigen Celoron oder auch Sempron Modellen...

Hier kann man sich aber auch gut die Info des gcc zunutze machen und schauen was er mit -march=native selbst für eine reale -march verwenden würde, dies ist zb in der Ausgabe von 

```
$ cd /tmp

$ echo 'int main(){return 0;}' > test.c && gcc -v -Q -march=native -O2 test.c -o test && rm test.c test
```

 recht gut ersichtlich. (ist nicht von mir, hab ich hier im Forum irgendwo mal entdeckt)

Ansonsten (wenn auch schon alt) aber dennoch interessant -> der Thread Aggressive CFlags

Ich würde das ganze erst mal sachte angehen und es mit den Optimierungen nicht übertreiben, denn kaputt-optimieren bringt einem ja auch nichts...  :Wink: 

----------

## mv

 *aleph-muc wrote:*   

> das Problem ist nicht, dass sich der kompilierte Code nicht ausführen läßt, sondern dass sich der Code mit zu aggressiven Flags nicht kompilieren läßt.

 

Nein. Es kann beides passieren. Beispielsweise kann code, der mit -finline-functions compiliert ist, manchmal nicht gelinkt werden (weil die entsprechenden Symbole nicht exportiert werden); wenn das Linken erst zur Laufzeit passiert (etwa bei plugins), merkt man das eben erst dann.

Hässlicher sind Dinge wie -ftree-vectorize, die erwarten, dass eine bestimmte Datenstruktur im Stack "aligned" ist. Wenn das aus irgendeinem Grund nicht der Fall ist (etwa weil die Struktur per Assembler gebaut wird oder aus einer Bilbliothek kommt, die eben nicht "aligned") gibt es einen Segfault. Das alignen kann man zwar mit -mstackrealign erzwingen und so den Sefault vermeiden, aber das Erzwingen kostet natürlich auch wieder Zeit.

----------

## FrancisA

 *mv wrote:*   

>  *aleph-muc wrote:*   das Problem ist nicht, dass sich der kompilierte Code nicht ausführen läßt, sondern dass sich der Code mit zu aggressiven Flags nicht kompilieren läßt. 
> 
> Nein. Es kann beides passieren. Beispielsweise kann code, der mit -finline-functions compiliert ist, manchmal nicht gelinkt werden 
> 
> [...]
> ...

 

Wobei es dann wahrscheinlich besser ist, wenn sich die Anwendung gleich nicht compilieren lässt (und dann auf eine niedrigere Stufe zurückstellen muss), als eine fehlerhafte Applikation zu haben.

----------

## kernelOfTruth

 *FrancisA wrote:*   

>  *mv wrote:*    *aleph-muc wrote:*   das Problem ist nicht, dass sich der kompilierte Code nicht ausführen läßt, sondern dass sich der Code mit zu aggressiven Flags nicht kompilieren läßt. 
> 
> Nein. Es kann beides passieren. Beispielsweise kann code, der mit -finline-functions compiliert ist, manchmal nicht gelinkt werden 
> 
> [...]
> ...

 

naja, vor allem kannst du dir dadurch das aufwändige neu kompilieren der Abhängigkeiten sparen, wenn eine Abhängigkeit problemlos durchgelaufen wäre, aber fehlerhaft läuft

----------

## mv

 *FrancisA wrote:*   

> Wobei es dann wahrscheinlich besser ist, wenn sich die Anwendung gleich nicht compilieren lässt

 

Klar wäre das besser. Das Gefährliche bei den CFLAGS/LDFLAGS ist halt, dass man sich das nicht heraussuchen kann - es können diese und jene Effekte eintreten, und wenn man Anwendung und Compiler nicht genau kennt, sollte man daher im Zweifelsfall besser die Finger von lasssen - oder sich zumindest bewusst sein, dass man mit dem Feuer spielt.

----------

## Yamakuzure

Soweit ich weiß gibt es nur zwei Pakete, bei denen -O3 sinnvoll ist: sqlite und python. Bei allen anderen sollte man tunlichst bei -O2 bleiben. Zumindest laut dieser Quelle: http://www.gentoo-wiki.info/CflagsExceptions#-O3

----------

## mv

 *Yamakuzure wrote:*   

> Soweit ich weiß gibt es nur zwei Pakete, bei denen -O3 sinnvoll ist: sqlite und python.

 

Das ist in dieser Allgemeinheit ein ziemlicher Humbug: Ob -O3 etwas bringt oder nicht, hängt in erster Linie vom Prozessor ab. AMD-Prozessoren haben anscheinend viel Cache, da bringt -O3 in der Regel gewaltig etwas, bei Intel-Prozessoren ist meistens die Code-Größe wichtiger für die Geschwindigkeit; aber das kann von Prozessormodell zu -Modell stark variieren. Beim Programm hängt es dann ebenfalls von vielen Faktoren ab, ob -O3 etwas bringt: Wenn der Code durch -O3 gerade ein paar Bytes zu lange wird und dadurch eine Pipeline zusammenbricht, verliert man mehr Zeit; andererseits kann durch -O3 die Branch-Prediction mal besser liegen. Eine minimale Änderung am Code (semantisch äquivalent) kann da schon ganz andere Ergebnisse bringen. Und gerade bei sqlite, das i.W. durch die IO-Geschwindigkeit bestimmt wird, ist die Prozessoroptimierung weitgehend wurst. Dass bei bestimmten Rechnern bestimmte Programme mit -O3 deutlich schneller sind, glaube ich gerne, aber welche das sind, kann man kaum vorhersagen. sqlite und python sind sicher nicht die idealen Kandidaten für -O3. Wichtigere Kandidaten sind Multimedia-Applikationen (bei denen die Geschwindigkeit ja auch wirklich wichtig sein kann).

----------

## JoHo42

Hi Leute,

mein Tip wenn man sich  dafür wirklich interessiert, dann sollte man sich das Dokument

für seine GCC Version unter www.gcc.gnu.org runterladen.

Dort kann man im Kapitel Options That Control Optimization

nachlesen welche Option bei -o3 eingeschaltet werden.

Bei -o2 ist schon einiges standart mässig an.

Bei -o3 kommen noch folgende hinzu:

 *Quote:*   

> 
> 
> Optimize yet more. ‘-O3’ turns on all optimizations specified by ‘-O2’
> 
> and also turns on the ‘-finline-functions’, ‘-funswitch-loops’,
> ...

 

Du kannst mal nachlesen welche was bewirkt und Dich dann entscheiden welche dabei

kommen sollen.

Wenn du alle einschaltest hast du natürlich wieder -o3.

Gruss Joerg

----------

## mv

 *JoHo42 wrote:*   

> Dort kann man im Kapitel Options That Control Optimization nachlesen welche Option bei -o3 eingeschaltet werden.

 

Das hängt aber jeweils von der Compiler-Version ab. Beispielsweise ist -ftree-vectorize erst seit gcc-4.5 (oder war es 4.4?) in -O3 enthalten und früher war auch mal -ftracer und -fweb in -O3 enthalten. Besser ist es, man lässt sich vom Compiler selbst ausgeben, welche Flags aktiviert sind:

```
gcc -c -Q -O3 -o /dev/null --help=optimizer
```

----------

## JoHo42

Hi mv,

darum hatte ich auch geschrieben für seine GCC Version.

OK schlechtes Deutsch.

Vielleicht sollte man noch eins sagen, dass die Optimierung nicht immer für einen

normalen PC oder Laptop geeigent sind sondern auch für andere Processoren.

Der GCC wird auch im bereich der Microcontroler eingesetzt und dort kann man

mehr erreichen mit den Optimierungen als auf einem PC.

Naja wer damit spielen will soll es machen, nur ob es immer was bringt wag ich mal

arg zu bezweifeln.

Gruss Joerg

----------

