Das ist ziemlich Standard in der Softwareentwicklung als Ganzes - wenn Sie Code zu optimieren, wird der Compiler erlaubt, die Dinge neu ordnen ziemlich aber es will, solange man keinen Unterschied in Betrieb berichten. So zum Beispiel, wenn Sie eine Variable innerhalb jeder Iteration einer Schleife zu initialisieren, und nie die Variable innerhalb der Schleife ändern, wird der Optimierer, dass die Initialisierung aus der Schleife bewegen kann, so dass Sie nicht Zeit damit verschwenden.
Es kann auch vorkommen, dass Sie eine Zahl berechnen, mit der Sie dann nichts mehr tun, bevor Sie sie überschreiben. In diesem Fall könnte es die nutzlose Berechnung beseitigen.
Das Problem mit der Optimierung ist, dass Sie auf einige Stück Code einen Haltepunkt setzen wollen werden, die der Optimierer bewegt hat oder eliminiert. In diesem Fall kann der Debugger nicht tun, was Sie wollen (in der Regel wird es den Haltepunkt irgendwo in der Nähe setzen). Also, um den generierten Code stärker ähneln, was Sie geschrieben, Sie deaktivieren Optimierungen während debug - Dies stellt sicher, dass der Code, den Sie brechen auf wirklich wollen, gibt es.
Sie müssen jedoch vorsichtig sein, da die Optimierung je nach Code zu Problemen führen kann! Im allgemeinen Code, der von einem korrekt funktionierenden Optimierer gebrochen ist wirklich nur Buggy-Code, der mit etwas entkommt, so dass Sie in der Regel, warum der Optimierer bricht es herauszufinden wollen.
Ich habe diese Frage an Jack Ganssle gesendet und er hat mir Folgendes geantwortet:
quelle
Abhängt, und dies ist in der Regel gilt für alle Werkzeuge nicht nur C30.
Optimierungen oft entfernen und / oder Umstrukturierung des Codes auf verschiedene Weise. Ihre switch-Anweisung kann mit einem, wenn / else Konstrukt oder in einigen Fällen neu implementiert bekommen werden alle zusammen entfernt. y = x * 16 kann mit einer Reihe von Linksverschiebungen ersetzt bekommen, usw., obwohl diese letzte Art der Optimierung in der Regel nach wie vor durch verstärkt werden kann, seine meist die Umstrukturierung der Steueranweisung, ya bekommt.
Dies kann es unmöglich machen, einen Debugger durch Ihren C-Code zu führen, da die von Ihnen in C definierten Strukturen nicht mehr existieren. Sie wurden vom Compiler ersetzt oder neu angeordnet, sodass der Compiler der Ansicht ist, dass sie schneller sind oder weniger Speicherplatz beanspruchen. Es kann auch Ihr Bruch auf, nicht länger besteht, da die Anweisung Auflistung Stützpunkte unmöglich Satz aus dem C machen. Zum Beispiel können Sie versuchen, einen Haltepunkt in einer if-Anweisung zu setzen, aber der Compiler entfernt haben kann, dass, wenn. Sie können versuchen, einen Haltepunkt innerhalb einer while- oder for-Schleife zu setzen, aber der Compiler hat beschlossen, diese Schleife zu entrollen, damit sie nicht mehr existiert.
Aus diesem Grund können , wenn Sie mit Optimierungen debuggen aus, seine in der Regel einfacher. Sie sollten immer Retest mit Optimierungen auf. Dies ist über die einzige Art und Weise werden Sie feststellen , dass Sie einen wichtigen verpasst
volatile
und seine was zu sporadischen Ausfällen (oder eine andere Seltsamkeit).Im Fall der Embedded-Entwicklung, müssen Sie auf jeden Fall mit Optimierungen vorsichtig sein. Speziell in Codeabschnitten, das Timing kritisch, einige Interrupts zum Beispiel. In diesen Fällen sollten Sie entweder Code der kritischen Bits in der Montage oder Richtlinien Verwendung Compiler um sicherzustellen, dass diese Abschnitte nicht optimiert werden, so dass Sie wissen, dass sie eine feste Ausführungszeit oder eine Worst-Case-Laufzeit festgelegt.
Der andere gotcha kann Code in das uC werden passend, können Sie Codedichte Optimierungen müssen einfach den Code in den Chip passen.
quelle
Wenn ich optimierten Code veröffentlichen würde, würde ich mit optimierten Code debuggen. Wenn ich nicht optimierten Code veröffentlichen würde, würde ich mit nicht optimierten Code debuggen. Ich tue dies aus zwei Gründen. Erstens kann Optimizern signifikant genug Timing Unterschiede machen das Endprodukt verursachen anders als nicht optimierte Code zu verhalten. Zweitens, obwohl die meisten sind ziemlich gut, Compiler-Anbieter tun machen Fehler und optimierten Code unterschiedliche Ergebnisse aus nicht optimierten Code erzeugen. Als Ergebnis, wie ich mit so viel Testzeit wie möglich zu bekommen, was Einstellung, ich plane, mit zu lösen.
Davon abgesehen, können Optimizern schwierig machen, das Debuggen, wie in den vorherigen Antworten zur Kenntnis genommen. Wenn ich einen bestimmten Codeabschnitt finden, die schwer zu debuggen ist, werde ich vorübergehend das Optimierungsprogramm deaktivieren, führen Sie die Debuggen den Code zum Laufen zu bringen, dann drehen Sie den Optimierer wieder auf und testen Sie noch einmal.
quelle
Meine normale Strategie ist mit der endgültigen Optimierung (max für Größe oder Geschwindigkeit je nach Fall), sondern spiegeln die Optimierung off vorübergehend zu entwickeln, wenn ich ot Spur etwas debuggen müssen. Dies reduziert das Risiko von Fehlern infolge Oberflächenoptimierungsstufen zu ändern.
Ein typischer Fehlermodus ist, wenn zunehmende Optimierung bisher unbekannte Bugs Oberfläche verursacht aufgrund Sie nicht als flüchtigen deklarierten Variablen mit, wo erforderlich - dies ist wichtig, den Compiler zu sagen, welche Dinge sollen nicht ‚optimierten‘ werden.
quelle
Verwenden Sie jedes Formular, mit dem Sie veröffentlichen möchten, Debugger und Kompilierer zum Debuggen, um eine Menge (VIELE) Fehler zu verbergen, die Sie erst sehen, wenn Sie für die Veröffentlichung kompilieren. Bis dahin ist es viel schwieriger, diese Fehler zu finden, als das Debuggen, während Sie gehen. 20 etwas Jahre und ich nie eine Verwendung für ein GDB oder andere wie Debugger hatte, keine Notwendigkeit, Variablen oder einzelnen Schritt zu beobachten. Hunderttausende von Zeilen pro Tag. Es ist also möglich, dass Sie nicht dazu gebracht werden, etwas anderes zu denken.
Das Kompilieren für das Debuggen und das spätere Kompilieren für die Veröffentlichung kann und wird den doppelten bis mehr als doppelten Aufwand erfordern. Wenn Sie in einen Bind geraten und ein Tool wie einen Debugger verwenden müssen, kompilieren Sie, damit der Debugger das spezifische Problem löst, und kehren Sie dann zum normalen Betrieb zurück.
Andere Probleme sind auch wahr, wie der Optimierer des Code macht so schneller für insbesondere Ihr Timing Änderungen mit Compiler-Optionen eingebettet und dass die Funktionalität des Programms beeinflussen kann, benutzen Sie wieder die zu liefernde Compilierung Wahl während der gesamten Phase. Compiler sind ebenfalls Programme und haben Bugs und Optimierer, die Fehler machen, und manche glauben nicht daran. Wenn das der Fall ist, gibt es nichts falsch mit ihm ohne Optimierung kompilieren, es einfach so tut die ganze Zeit. Der von mir bevorzugte Pfad ist die Kompilierung für die Optimierung. Wenn ich ein Compilerproblem vermute, deaktivieren Sie die Optimierung, wenn dies das Problem behebt. Gehen Sie in der Regel hin und her und überprüfen Sie manchmal die Assembler-Ausgabe, um herauszufinden, warum.
quelle
Ich entwickle immer Code mit -O0 (gcc Option aktivieren Optimierung off). Wenn ich das Gefühl habe, an dem Punkt angelangt zu sein, an dem ich die Dinge mehr auf ein Release zusteuern lassen möchte, beginne ich mit -Os (für die Größe optimieren), da es im Allgemeinen umso besser ist, je mehr Code im Cache gespeichert werden kann. auch wenn es nicht super-duper optimiert ist.
Ich finde, dass gdb funktioniert viel besser mit -O0 Code, und es ist viel einfacher zu folgen, wenn Sie Schritt in die Baugruppe haben. Hin- und Herschalten zwischen -O0 und -Os können Sie auch sehen, was der Compiler Code tut. Es ist zuweilen eine ziemlich interessante Ausbildung und kann auch Compiler-Bugs aufdecken ... diese fiesen Dinge, die Sie dazu bringen, sich die Haare auszureißen und herauszufinden, was mit Ihrem Code nicht stimmt!
Wenn es wirklich nötig ist, füge ich in -fdata-Abschnitten und -fcode-Abschnitten --gc-Abschnitte hinzu, mit denen der Linker ganze Funktionen und Datensegmente entfernen kann, die eigentlich nicht verwendet werden. Es gibt viele kleine Dinge, die Sie mit basteln können, um zu versuchen die Dinge weiter nach unten oder den Dingen schneller schrumpfen, aber im Großen und Ganzen diese die einzigen Tricks sind mit ich am Ende, und alles, was kleiner oder schneller sein muß ich die Hand -montieren.
quelle
Ja, das Deaktivieren von Optimierungen während des Debuggens hat sich aus drei Gründen seit einiger Zeit bewährt:
Viele Menschen gehen sogar noch weiter in dieser Richtung, und Schiff mit Behauptungen eingeschaltet .
quelle
Ganz einfach: Optimierungen sind zeitintensiv und kann nutzlos sein , wenn Sie dieses Stück Code ändern müssen , um später in der Entwicklung. So können sie auch eine Verschwendung von Zeit und Geld.
Sie sind jedoch für fertige Module nützlich. Teile des Codes, die wahrscheinlich keine Änderungen mehr benötigen.
quelle
sicherlich macht es Sinn, im Fall von Bruchstellen ... wie die Compiler viele Aussagen entfernen, die nicht wirklich Memory-Effekt zu tun.
Sehen Sie so etwas wie:
vollständig optimiert werden kann (weil
i
nicht immer lesen). es aus der Sicht des Breakpoint aussehen würde , dass es all dieser Codes übersprungen, wenn es im Grunde war einfach gar nicht da .... gehe ich davon aus, dass bin , warum in Funktionen Schlaf Typ oft Sie so etwas wie sehen:quelle
Wenn Sie den Debugger verwenden, dann würde ich Optimierungen deaktivieren und zu debuggen aktivieren.
Persönlich finde ich , dass die PIC - Debugger mehr Probleme verursacht , als es hilft mir zu beheben.
Ich benutze nur printf () zu USART meine Programme in C18 geschrieben zu debuggen.
quelle
Die meisten Argumente gegen ermöglicht Optimierung in Ihrer Compilierung kommen auf:
IMHO die ersten beiden sind echt, die dritte nicht so sehr. Es bedeutet oft Sie einige schlechte Code haben oder auf unsichere Ausbeutung der Sprache / Implementierung setzen oder vielleicht der Autor ist nur ein Fan von guten alten Onkel nicht definiertes Verhalten.
Der Embedded in Academia Blog hat ein oder zwei Dinge über zu undefiniertem Verhalten zu sagen, und dieser Beitrag ist, wie Compiler auszubeuten: http://blog.regehr.org/archives/761
quelle