2015-12-13 16 views
7

Ich bin seit 13 Jahren Software Engineer in verschiedenen Sprachen, obwohl ich gerade erst in C und später in C++ bin. Während ich C lerne, benutze ich den GCC-Compiler, um meine Programme zu kompilieren, und ich frage mich, ob es irgendwelche Fehler gibt, -O3 oder andere Optimierungs-Flags zu benutzen. Gibt es eine Chance, dass meine Software in einer Weise einbricht, die ich ohne den kompilierten Code nicht erfassen kann, oder vielleicht während der Cross-Compilation, dass ich versehentlich etwas für eine andere Plattform durcheinander bringen könnte.Gibt es Nachteile bei der Verwendung von -O3 in GCC?

Bevor ich diese Optionen blind einschalte, würde ich gerne wissen, was ich erwarten kann. Auch wenn -Ofast nicht standardkonforme Flags aktiviert, möchte ich das nicht verwenden. Bin ich richtig in meinen Annahmen, dass -Ofast höchstwahrscheinlich "Nebenwirkungen" haben wird?

Ich habe einen Blick auf https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html geworfen, bevor ich diese Frage gepostet habe.

+0

Ich denke, es ist ein Fall von -O2 hat viel mehr Laufleistung als -O3. Ich würde empfehlen, dass Sie sicherstellen, dass Sie die Binärdateien testen ... –

+2

Sie sollten alle Ihre Binärdateien sowieso testen ... –

+0

@dwelch Sie haben Recht. Nachdem ich das über die Tests geschrieben hatte, wurde mir klar, dass ich es nicht testen konnte, bevor es kompiliert wurde. Ich denke, ich bin es gewohnt, Sprachtests zu schreiben, bei denen ich der öffentlichen Schnittstelle ausweichen kann. –

Antwort

7

Der einzige Nachteil von -O3 sollte die Unfähigkeit sein, den Code in einem Debugger zu folgen.

Die Verwendung von -Ofast kann einige Ihrer Gleitkommaoperationen beeinträchtigen, was Rundungsfehler verursacht. Wenn Sie jedoch keine besonders langen Ketten von Gleitkommaberechnungen ausführen, werden Sie dies wahrscheinlich nie bemerken.

Gebrochener Code (Code mit ungültigen Zeigern oder Anweisungen mit undefiniertem Verhalten) verhält sich wahrscheinlich auf verschiedenen Optimierungsebenen unterschiedlich - die erste Reaktion vieler Programmierer ist die Schuld des Compilers - das Ermöglichen aller Warnungen und deren Behebung hilft normalerweise .

+0

Warnungen und Fehler sind nicht standardmäßig aktiviert? Das ist Scheiße. Ich nehme an, dass ich "-Wall" und "-Eall" dafür verwende? Ich habe gerade gefunden, wie man (buchstäblich) ALLE Warnungen des GCC einschaltet?] (Http://stackoverflow.com/questions/11714827/how-to-turn-on-literally-all-of-gccs-warnings). –

+1

Im Gegensatz zu dem, was Sie glauben würden '' '' '' '' '' '' '' '' '' '' '' nicht alle Warnungen aktivieren, sondern nur die nützlichste - es gibt mehr Warnungen, die Sie hier überprüfen können (https://gcc.gnu.org/onlinedocs/gcc/ Warning-Options.html) – Soren

+3

@RickMacGillis '-Wall -Wextra -pedantic' ist praktisch, und denken Sie auch daran, einen Sprachstandard manuell anzugeben (' -std = c11' oder '-std = C++ 14'), oder es wird Ihnen stattdessen GNU-Modus mit einer Reihe von (nützliche, aber nicht standardmäßige) Erweiterungen geben. – Leushenko

1

Da -O3 beginnt, den Code zu verschieben, um ihn zu optimieren, können Sie in einigen Fällen feststellen, dass Ihre Ergebnisse unterschiedlich sind oder Ihre Pausen.

Wenn Sie Ihren Code mit -O3 auf Korrektheit testen und ein Problem finden, das Sie nicht debuggen können, wird empfohlen, zu -O0 zu wechseln, um zu sehen, ob Sie das gleiche Verhalten erhalten.

+2

Der konforme Code darf sich nicht anders verhalten als vom Standard gefordert. Und die Änderung der Optimierung für das Debugging bringt Sie nicht weiter, außer pures Glück. (Das hat nichts mit den Problemen zu tun, die optimierten Code debuggen; im Allgemeinen sollte man beim Debugging "e" = g "nehmen - angenommen gcc). – Olaf

+0

True, aber nicht alle Codes sind Standard und/oder gut geschrieben. Ich habe dieses Verhalten besonders in wissenschaftlichen Codes mit sehr vielen Zeilen gesehen. – Ashkan

+0

Deshalb habe ich mit "Compliant code ..." begonnen. Die Frage kann nicht ohne eine Code-Überprüfung beantwortet werden. – Olaf

4

Es ist wichtig, daran zu denken, dass fast alle Compiler-Optimierungen Heuristik sind. Mit anderen Worten, eine "Optimisierung" ist nur ein Versuch, um Ihr Programm "optimaler" zu machen, aber es könnte sehr wohl den gegenteiligen Effekt haben. Nur weil -O3 soll besser sein als -O2, und -O2 sollte besser sein als -O1-das heißt nicht, dass es in der Tat immer so ist, wie es funktioniert.

Manchmal kann eine von -O3 aktivierte "Optimierung" Ihr Programm verlangsamen, wenn es mit der mit -O2 oder -O1 erstellten Version verglichen wird. Sie sollten mit verschiedenen Optimierungsebenen experimentieren, um herauszufinden, was für Ihren spezifischen Code am besten funktioniert. Sie können sogar einzelne Optimierungen ein- und ausschalten, wenn Sie sie wirklich optimieren möchten.

Also kurz gesagt - ja, es kann Nachteile geben, -O3 zu verwenden. Ich habe persönlich beobachtet, dass eine Menge Zeug, das ich geschrieben habe, besser mit -O2 als mit -O3 funktioniert - aber das ist wirklich Programm-spezifisch.


FYI, hier ist eine andere SO fordern, dass die Frage, warum -O2 bessere Ergebnisse als -O3 für ein bestimmtes Programm gibt: gcc optimization flag -O3 makes code slower then -O2

1

„Ich möchte wissen, was ich erwarten kann“

Ich verwende C++ (meist GCC auf vxWorks) in eingebetteten Systemen seit mehr als 2 Jahrzehnten. Ich habe großen Respekt vor den Compiler-Autoren.


Vertrauen Sie Ihrem Compiler: IMHO hat O3 nie Code gebrochen ... hat aber bei Gelegenheit ergab interessante Codierungsfehler.


wählen: Teams müssen sich entscheiden, ob nicht zu „versenden, was Sie testen und testen, was Sie versenden“, unabhängig von -O1 oder O3 Wahl. Die Teams, mit denen ich gearbeitet habe, haben sich immer dazu verpflichtet, mit -O3 zu versenden und zu testen.


Single Step kann un-kooperativ sein: Auf eine persönliche Praxis Ebene, wenn O3-Code, ich in der Regel einzigen Schritt 'verlassen' gdb. Ich verwende viel mehr Breakpoints, und es gibt geringfügige Variationen in den Codierungsoptionen, um automatische Variablen (Stapeldaten) und Klassendaten "sichtbarer" zu machen. (Du kannst den gdb-Befehl 'p' für deinen unbequemen Freund machen).


Einzel Schritt ist notwendig: Bitte beachten Sie, dass, obwohl wir „Test und Schiff“ d O3 mit, wir fast ausschließlich -O1 Code debuggt werden.


Debug ist necesary: ​​Der Kompromiss zwischen Debuggen -01 noch testen und Versand O3 ist die zusätzliche Wieder compiles benötigt, um die beiden ausführbaren Dateien zu wechseln. Die Zeit, die in -O1 gespeichert wurde, um die Code-Bugs zu untersuchen, zu identifizieren und zu beheben, muss die zwei Neuerstellungen ausmachen (bis -01 und zurück zu -O3).


Regression Test Automation: Ich möchte Systeme Test sagen (auch bekannt als Integrationstest oder Regressionstest) von O3 es zu Schritt hat eine Kerbe, aber ich kann es nicht wirklich beschreiben ... vielleicht sollte ich empfehlen, dass das Niveau der Testautomatisierung höher ist (jeder REGURIONSTEST!). Aber ich bin mir nicht sicher. Die Automatisierungsebene des Regressionstests korreliert wahrscheinlich eher mit der Teamgröße als mit dem Leistungsniveau.


Ein "erfolgreiches" eingebettetes System macht 2 Dinge. Es erfüllt die Anforderungen. Und, was noch wichtiger ist, in allem menschlichen sichtbaren Verhalten verhält es sich wie ein leicht belasteter Desktop. Für jede Aktion (Knopfdruck, Kabeltrennung, Testgerät-induzierter Fehler oder sogar eine geringe Statuslichtänderung) haben die Ergebnisse keine vom Menschen wahrnehmbare Verzögerung. -O3 hilft. Ein erfolgreiches System kann getan werden ... Ich habe es gesehen.

Verwandte Themen