Frage

Ich habe ein echtes seltsames Problem GCC für ARM mit mit den Optimierungen eingeschaltet. Kompilieren meine C ++ Anwendung, ohne dass die Optimierungen erzeugt eine ausführbare Datei, die zur Laufzeit gibt die erwarteten Ergebnisse. Sobald ich auf dem Turn Optimierungen - die -O1 ist - meine Anwendung nicht die erwarteten Ergebnisse zu erzielen. Ich habe versucht, für ein paar Tage, um das Problem zu erkennen, aber ich bin ratlos. Ich eliminiert alle nicht initialisierten Variablen aus meinem Code, ich korrigiert, um die Stellen, an denen strenge Aliasing Probleme verursachen könnte, aber noch habe ich nicht die richtigen Ergebnisse.

Ich bin mit GCC 4.2.0 für ARM (der Prozessor ist ein ARM926EJ-S) und den Betrieb der App auf einer Montavista Linux-Distribution.

Im Folgenden sind die Fahnen Ich verwende:

-O1 -fno-unroll-loops fno-merge-constants -fno-omit-frame-pointer -fno-toplevel-reorder \
-fno-defer-pop -fno-function-cse -Wuninitialized -Wstrict-aliasing=3 -Wstrict-overflow=3 \
-fsigned-char -march=armv5te -mtune=arm926ej-s -ffast-math

Sobald ich die -O1 Flagge und recompile Streifen / relink die Anwendung erhalte ich die richtigen Ausgabeergebnisse. Wie Sie aus den Fahnen sehen kann ich jede Optimierung zu deaktivieren versucht, dachte ich, es zu Problemen führen könnte, aber noch kein Glück.

hat jemand irgendwelche Hinweise auf, wie ich dieses Problem weiter angehen könnte?

Danke

War es hilfreich?

Lösung

Generell, wenn Sie sagen, „Optimierung mein Programm bricht“, es ist 99,9% der Programm , die gebrochen wird. Aktivieren Optimierungen nur freigibt die Fehler im Code.

Sie sollten auch einfach auf die Optimierungsmöglichkeiten gehen. Nur unter ganz bestimmten Umständen müssen Sie noch etwas über die Standardoptionen -O0, -O2, O3 und vielleicht -Os. Wenn Sie Sie Fühlen Sie sich , dass spezifischere Einstellungen als das, beherzigen das Mantra von Optimierungen:

Messen, optimize, messen.

Nie geht von "Bauchgefühl" hier. Beweisen Sie, dass eine bestimmte Nicht-Standard-Optimierungsoption erheblich Ihre Anwendung nicht profitieren, und verstehen, warum (das heißt, genau verstehen, was diese Option tut, und warum es wirkt sich Ihr Code).

Dies ist kein guter Ort, um navigate die Augen verbunden.

Und zu sehen, wie Sie die meisten defensive Option (-O1), dann deaktivieren Sie ein halbes Dutzend Optimierungen und und in -ffast-Mathe, führt mich, Sie zu übernehmen sind zur Zeit nur tun, dass .

Nun, vielleicht einäugige.

Aber das Endergebnis ist. Wenn ermöglicht Optimierung Code bricht, ist es sehr wahrscheinlich Fehler Ihres Codes

EDIT: Ich habe gerade diese in der GCC-Handbuch:

  

-ffast-math: Diese Option sollte niemals durch irgendeine Option -O gedreht werden    da es für die Programme fehlerhafte Ausgabe führen, die davon abhängen,   eine exakte Umsetzung der IEEE oder ISO-Regeln / Spezifikationen für Mathematik   Funktionen.

Das sagt, im Grunde, dass Ihr -O1 -ffast-math tatsächlich brechen könnte richtig Code. Doch selbst wenn Wegnehmen -ffast-math Ihr aktuelles Problem beseitigt, sollten Sie zumindest eine Idee haben, Warum . Ansonsten könnten Sie nur Ihr Problem austauschen jetzt mit einem Problem in einem unpassenden Moment später (wie, wenn Ihr Produkt bricht bei Ihren Kunden Standort). Ist es wirklich -ffast-math, dass das Problem war, oder haben Sie Mathe Code gebrochen, das ist entdeckt von -ffast-math?

Andere Tipps

-ffast-math sollte möglichst vermieden werden. verwenden -O1 nur für jetzt und fallen alle anderen Optimierungs Switches. Wenn Sie immer noch Probleme, dann ist es Zeit zu sehen beginnen debuggen.

Ohne Code zu sehen, es ist schwer, präziser zu bekommen, als „Sie möglicherweise einen Fehler haben.“

Es gibt zwei Szenarien, in denen ermöglicht Optimierungen, die Semantik des Programms ändert:

  • gibt es einen Fehler im Compiler oder
  • gibt es einen Fehler im Code.

Letzteres ist wahrscheinlich die am wahrscheinlichsten. Insbesondere setzen Sie wahrscheinlich auf undefiniertes Verhalten irgendwo in Ihrem Programm. Sie verlassen sich auf etwas, das nur so wahr sein passieren, wenn Sie kompilieren mit das Compiler auf das Computer mit diese Compiler-Flags, die aber isn‘ t garantiert durch die Sprache. Und so, wenn Sie Optimierungen ermöglichen, GCC nicht verpflichtet ist, dieses Verhalten zu bewahren.

Zeigen Sie uns Ihren Code. Oder Schritt durch sie im Debugger, bis Sie zu dem Punkt, wo etwas schief geht.

Ich kann nicht mehr spezifisch sein. Es könnte ein baumelnden Zeiger, nicht initialisierte Variablen sein, die Aliasing-Regeln zu brechen, oder auch nur eine der viele Dinge zu tun, dass Ausbeute Ergebnisse nicht definiert (wie i = i++)

Versuchen Sie, einen minimalen Testfall zu machen. Rewrite das Programm, das Entfernen Dinge, die den Fehler nicht beeinflussen. Es ist wahrscheinlich, dass Sie den Fehler selbst in dem Prozess werden entdecken, aber wenn Sie nicht tun, sollten Sie einen Ein-Bildschirm Beispielprogramm haben Sie können Post.

Im Übrigen , wenn , wie andere spekuliert haben, ist es -ffast-math, die Ihre Probleme verursacht (dh Compilieren mit nur -O1 funktioniert gut), dann ist es wahrscheinlich, dass Sie einige mathematische haben dort sollten Sie umschreiben sowieso . Es ist ein bisschen einer übertriebene Vereinfachung, aber -ffast-math ermöglicht den Compiler im Wesentlichen neu anordnen Berechnungen, wie Sie abstrakte mathematische Zahlen können - obwohl auf echte Hardware so zu tun verursachen kann leicht unterschiedliche Ergebnisse, da Gleitkommazahlen sind nicht exakt. Unter Berufung auf diese Art von Punkt Detail schwimmt, ist wahrscheinlich unbeabsichtigt sein.

Wenn Sie den Fehler, ein minimaler Testfall ist von entscheidender Bedeutung in jedem Fall verstehen wollen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top