Ich kompiliere mit dem AVR-gcc und der Optimization -O1. Innerhalb einer
Funktion verwende ich
1
if(zahl)
2
{
3
//fuehre aus
4
}
.
Dabei ist zahl 0 oder eine andere Zahl. Zahl ist außerdem per
1
#define zahl 0
definiert. Die Funktion soll also nur dann etwas bewirken wenn zahl!=0.
Ich könnte beim Aufruf auch schreiben
1
if(zahl)function();
,was augenscheinlich besser zu sein scheint, denn damit wird definitiv
verhindert, dass die Funktion überhaupt aufgerufen wird.
(Zeitersparnis?)
Wird im Fall der genannten Optimization das eventuelle Laufzeitdefizit
im ersteren Fall erkannt und die Funktion NICHT aufgerufen wenn zahl
"null" ist? Oder ist dafür eine höherwertige Optimization erforderlich?
Floh schrieb:> Wenn zahl durch eine 0 ersetzt wird (im Präprozessor), ist die Abfrage> if(zahl) witzlos, da das sofort durch den Compiler wegoptimiert wird.
Ersteinmal ist hier nix witzlos. Ich glaube das Problem wurde noch nicht
erkannt.
Die Abfrage macht schon Sinn, wenn der Aufruf der Funktion im Programm
nicht überall von Hand gelöscht werden soll, nur weil eine
kundenspezifische Firmware erstellt wird.
Ich wollte eher wissen ob auch der Funktionsaufruf! durch den Compiler
wegoptimiert wird, wenn IN der Funktion if(zahl) steht und somit die
Funktion wirkungslos wird. (Ob Ja oder Nein in beiden Fällen wird die
Funktion wirkungslos... aber wird sie aufgerufen??)
Gruß Maddin
Wenn Inlining nicht vollständig ausgeschlossen ist und dem Compiler der
Inhalt der Funktion bekannt ist, dann kann der Compiler eine leere
Funktion als überflüssig erkennen und den Aufruf wegoptimieren.
Maddin schrieb:> Floh schrieb:>> Wenn zahl durch eine 0 ersetzt wird (im Präprozessor), ist die Abfrage>> if(zahl) witzlos, da das sofort durch den Compiler wegoptimiert wird.>> Ersteinmal ist hier nix witzlos. Ich glaube das Problem wurde noch nicht> erkannt.
Ich glaube das Problem wurde nicht richtig beschrieben.
Was du willst ist, mit Präprozessor Hilfe, Teile deines Programmes gar
nicht erst mitkompilieren zu lassen
#if zahl == 0
function();
#endif
A. K. schrieb:> Wenn Inlining nicht vollständig ausgeschlossen ist und dem Compiler der> Inhalt der Funktion bekannt ist, dann kann der Compiler eine leere> Funktion als überflüssig erkennen und den Aufruf wegoptimieren.
Gut Inlining sagt mir nun nichts, aber ein definitives Ja oder Nein ist
es auch nicht. Aber das reicht mir als Beantwortung.
Karl Heinz Buchegger schrieb:> Was du willst ist, mit Präprozessor Hilfe, Teile deines Programmes gar> nicht erst mitkompilieren zu lassen
Schon Richtig.
Karl Heinz Buchegger schrieb:> #if zahl == 0> function();> #endif
Ob genau dies der Compiler bei der Optimierung vornimmt wollte ich
wissen. Unabhängig davon hast du mir damit jedoch einen wunderbaren
Vorschlag gegeben, meinen Code zu optimieren. An soetwas habe ich noch
garnich gedacht.
Vielen Dank euch
Wenn Programmteile schon bei der Compilierung zu/abgeschaltet werden
sollen, so macht man das üblicherweise mit Define Schalter (#ifdef/
#if..).
Damit wird der Code schon vom Präprozessor entfernt oder eingefügt.
Man ist dann nicht vom Codeoptimierer abhängig.
Es ist dann auch für Entwickler die den Programmcode anschaut
ersichtlich, dass die Funktion zur Compilierzeit zu/abgeschaltet werden.
Allgemein benötigt ein Funktionsaufruf mehr Zeit als Inline
(zusätzlicher Aufruf und return).
Was der Codeoptimierer daraus macht ist eine andere Sache.
Natürlich verwendet man trotzdem Funktionen weil es das Programm
übersichtlicher macht, Programmteile nur 1Mal vorhanden sind... .
Wenn
if(false) funktion();
wird die Funktion natürlich nicht aufgerufen.
Es entscheidet doch das if, ob die Funktion aufgerufen wird oder nicht.
Dabei wird der Funktionsaufruf übersprungen.
Bei
if (false)
{
// code
}
wir der Programmblock übersprungen.
-> gleicher Zeitbedarf für beide Versionen.
Natürlich ohne Betrachtung von Codeoptimierungen.
Gruss JensM
JensM schrieb:> if(false) funktion();> wird die Funktion natürlich nicht aufgerufen.> Es entscheidet doch das if, ob die Funktion aufgerufen wird oder nicht.> Dabei wird der Funktionsaufruf übersprungen.
Ja natürlich.
> Bei> if (false)> {> // code> }> wir der Programmblock übersprungen.
Richtig, aber dabei wurde bereits in die Funktion gesprungen, dann erst
wird geprüft und festgestellt, dass der Code nicht ausgeführt werden
soll.
> -> gleicher Zeitbedarf für beide Versionen.
Wirklich? Auch nach dem bereits in die Funktion gesprungen wurde?
Maddin schrieb:> Gut Inlining sagt mir nun nichts, aber ein definitives Ja oder Nein ist> es auch nicht.
Kann es auch nicht sein, weil dieses Verhalten von der Sprache her nicht
definiert ist und völlig vom Compiler und dessen Launen abhängt.
JensM schrieb:> Wenn> if(false) funktion();> wird die Funktion natürlich nicht aufgerufen.> Es entscheidet doch das if, ob die Funktion aufgerufen wird oder nicht.> Dabei wird der Funktionsaufruf übersprungen.
Nein, hier nicht (zumindest GCC). Es wird nicht nur die Funktion nicht
aufgerufen, sondern erst überhaupt kein Funktionsaufruf erzeugt.
Ebenso wird keine if-Abfrage erzeugt.
Bitte ein Beispielcode übersetzen und nachkontrollieren!
> Bei> if (false)> {> // code> }> wir der Programmblock übersprungen.
Nein, er wird komplett in die Tonne gekloppt.
> -> gleicher Zeitbedarf für beide Versionen.
Wieder korrekt, weil für beide Varianten der Codeverbrauch = 0 ist
Maddin schrieb:> Ich kompiliere mit dem AVR-gcc und der Optimization -O1. Innerhalb einer> Funktion verwende ich>
1
>if(zahl)
2
>{
3
>//fuehre aus
4
>}
5
>
.
>> Dabei ist zahl 0 oder eine andere Zahl. Zahl ist außerdem per>
1
>#definezahl0
2
>
definiert. Die Funktion soll also nur dann etwas bewirken wenn
> zahl!=0. Ich könnte beim Aufruf auch schreiben>
1
>if(zahl)function();
2
>
> ,was augenscheinlich besser zu sein scheint, denn damit wird definitiv> verhindert, dass die Funktion überhaupt aufgerufen wird.> (Zeitersparnis?)
Ja.
Besser wäre wie in anderen Antworten vorgeschlagen gleich den
Präprozessor dafür zu nehmen wie Gott es vorgesehen hat.
> Wird im Fall der genannten Optimization das eventuelle Laufzeitdefizit> im ersteren Fall erkannt und die Funktion NICHT aufgerufen wenn zahl> "null" ist? Oder ist dafür eine höherwertige Optimization erforderlich?
Das geht mit so ziemlich keiner Optimierung, der Compiler kann
realistischerweise weder die Funktion "verschwinden" lassen noch den
Aufruf weglassen - jedenfalls wenn Aufruf und Funktion in verschiedenen
Files sind.
Die Gründe sind simpel:
- man kann von einer Funktion die Adresse nehmen, gibt es mehr als ein
File kann der Compiler nicht wissen ob das irgendwo getan wird, deshalb
kann er die Funktion nicht komplett weglassen - sogar wenn sie leer ist,
- beim compilieren von File A weiss der Compiler nicht wie in File B, C,
... definierte Funktionen überhaupt aussehen, deshalb kann er den Aufruf
nicht einfach weglassen.
Ein Compiler der über alle Files optimiert könnte sowas rausfinden, mit
recht unschönen Folgen für Laufzeit und Speicherverbrauch.
Jasch schrieb:> Das geht mit so ziemlich keiner Optimierung, der Compiler kann> realistischerweise weder die Funktion "verschwinden" lassen noch den> Aufruf weglassen - jedenfalls wenn Aufruf und Funktion in verschiedenen> Files sind.
Dann lässt man das halt den Linker machen - mit den GNU-Tools geht das
via "-ffunction-sections" beim Compilieren und "-Wl,--gc-sections" beim
Linken.
> Ein Compiler der über alle Files optimiert könnte sowas rausfinden, mit> recht unschönen Folgen für Laufzeit und Speicherverbrauch.
"-fwhole-program" beim gcc, mit einigen Einschränkungen
wird eigentlich sonst noch jemand übel, wenn man hört dass jemand wie
"Maddin" KUNDENspezifische Software schreibt? Welcher Kunde hat denn
sowas verdient?
Vorkentnisse == 0 && Einarbeitungfähigkeiten == 0
Die Grundlegende Frage wird von jedem Anfänger-Optimierungs Tutorial
beantwortet... eigentlich direkt von dem das man bei google zuerst
findet, würde man die schlagworete der frage bei google mal eingeben.
P E I N L I C H .
http://lmgtfy. com/?q=gcc+code+optimization+if+statement
3. Link. http://tldp.org/LDP/LG/issue71/joshi.html
Nummer 5.
... schrieb:> wird eigentlich sonst noch jemand übel, wenn man hört dass jemand wie> "Maddin" KUNDENspezifische Software schreibt? Welcher Kunde hat denn> sowas verdient?>> Vorkentnisse == 0 && Einarbeitungfähigkeiten == 0>> Die Grundlegende Frage wird von jedem Anfänger-Optimierungs Tutorial> beantwortet... eigentlich direkt von dem das man bei google zuerst> findet, würde man die schlagworete der frage bei google mal eingeben.>> P E I N L I C H .>> http://lmgtfy. com/?q=gcc+code+optimization+if+statement>> 3. Link. http://tldp.org/LDP/LG/issue71/joshi.html>> Nummer 5.
Lächerlich bist hier nur du. Was fällt dir überhaupt ein mich auf diese
bescheuerte Art und Weise zu kritisieren?
Weißt du etwas über meine Arbeit, mein Projekt, meine Kunden oder meinen
Karrierehintergrund?
Vielleicht bin ich ein 39jähriger hochbezahlter Softwaredesigner der
gerade die Software der neuen VW-Lenkung programmiert. Dem sollte
soetwas peinlich sein.
Vielleicht bin ich ein einsamer Kuhbauer der in nächtlicher Stunde im
Keller rumbastelt und für seine Kunden (Kühe) vollelektronische
Kuhglocken programmiert. Sollte dem etwa die Frage peinlich sein?
Vielleicht bin ich ein junger Student der bereits jetzt in industriele
Projekte eingebunden ist. Neben dem Studium und in den Ferien
Erfahrungen sammelt die er später gebrauchen wird und Geld verdient und
die deutsche Kaufkraft deutlich steigert und dabei in der kleinen Firma
ein Knowhow-Träger ist (ich weiß das kann relativ sein).
Alles egal solange es um Auslieferung von Software an bezahlende Kunden
geht? Denke ich nicht!!
Die Software läuft sein Monaten, ist strukturiert und die zugehörige
Hardware zuverlässig! Und alles durch meinen eigenen Geist und
Tatendrang geschaffen! Ob dus glaubst oder nicht. Darauf bin ich
verdammt stolz. In ganz Deutschland, selbst in teilen Europa läuft meine
Software auf meiner Hardware. Diesen Erfolg kannst du mir mit deiner
PÖBELEI nicht nehmen!
Und noch einmal. Meine Frage ware einzieg und allein:
"Optimiert der Compiler eine komplette Funktion ja sogar deren Aufruf
weg, wenn deren INHALT augenscheinlich keine Bedeutung hat."
Ob dies durch google rauszufinden war? Ich weiß es nicht. Ich habe nicht
danach gesucht, weil ich annahm die Antwort sei nicht leicht zu finden.
(Und in Anbetracht meines (noch geringen) Stundenlohns zog ich dieses
Forum zu Rate.) Nun siehst du an Beiträgen wie von "A.K." und "Jasch"
das dies sogar zutrifft. Auf den Zusammenhang mit den unterschiedlichen
Files wäre ich auch nicht so gekommen.
Allen anderen danke ich für die sachliche Erklärung auch wenn das
angefallende Nebenprodukt mit dem
1
#define irgendwas
die Fragestellung beseitigt und den Code um einiges sauberer und zu dem
macht was es werden sollte.
So jetz bin ich froh dass das raus is. Du hast mich heute morgen echt
sauer gemacht. Aber wahrscheinlich hast du dein Ziel damit erreicht.
Gruß
Maddin
ikorb schrieb:> Jasch schrieb:>> Das geht mit so ziemlich keiner Optimierung, der Compiler kann>> realistischerweise weder die Funktion "verschwinden" lassen noch den>> Aufruf weglassen - jedenfalls wenn Aufruf und Funktion in verschiedenen>> Files sind.>> Dann lässt man das halt den Linker machen - mit den GNU-Tools geht das> via "-ffunction-sections" beim Compilieren und "-Wl,--gc-sections" beim> Linken.
Hmm, hmm. Kann der AVR-GCC das auch schon?
>> Ein Compiler der über alle Files optimiert könnte sowas rausfinden, mit>> recht unschönen Folgen für Laufzeit und Speicherverbrauch.>> "-fwhole-program" beim gcc, mit einigen Einschränkungen
Das dürfte eines der weniger getesteten Features sein, schliesslich ist
sowas bei grosser Software auf grossen Plattformen - ich denke da so an
Linux-Kernel, glibc, OpenOffice, grössere Embedded-Sachen, Sachen mit
5-, 6-, 7-stelliger Anzahl Codezeilen halt - wohl kaum praktikabel. Hah,
"Assume that the current compilation unit represents the whole program",
wie praktisch brauchbar ist das denn?
Überhaupt, es gibt ja Lösungen für das Problem die sogar laut Standard
funktionieren müssen - sich auf die nicht garantierten Eigenschaften
des Optimizers eines ganz bestimmten Compilers zu verlassen ist eher
mutig bis gegebenenfalls nervenzerfetzend.