Moin, moin Zum Thema "Hardwarenahe Programmierung" bin ich über den Punkt gestolpert, das verschiedenen Standards/Zertifizierungen ( im embedded-bereich) verlangen das die maschinelle Optimierung auszuschalten ist (cc -O0). Beim Nachzurecherchieren diese "Hörensagen" stoße ich auf Widersprüche. Mal steht bei MISRA-C (Automobilbereich, Softwarezuverlässigkeit) wäre das so und auch bei höheren SIL Stufen (IEC 61508, Avionic etc), dann erzählt mir ein erfahrenen MISRA-programmiere bei ihm hats immer auf -O3 gestanden trotz MISRA compliance. Welche Erfahrung habt ihr damit gemacht, wann musste die Optimierung wirklich deaktiviert werden, nach welchen Standard und für welche Zielhardware wurde dabei entwickelt? MfG,
Meine Erfahrung aus 61508-Projekten: Ein Projekt hatte diversitäre Kanäle, mit ganz unterschiedlichen Mikrocontroller-Architekturen und unterschiedlichen Compilern: gar kein Problem. Ein anderes Projekt hatte homogene Kanäle mit dem selben Compiler: eine Diskussion mit der Benannten Stelle fand statt, war aber schmerzlos. Etwas verschärfte Auflagen, was Testen angeht, kamen dabei heraus, Optimierung wurde akzeptiert. Man muß sich auch klar machen, daß "-O0" üblicherweise auch Optimierungen durchführt, nur halt die ganz einfachen. Irgendwann wird es sowieso philosophisch, wenn man das ganz konsequent durchziehen würde, dürfte kein Middle-End oder Back-End irgendwelche Änderungen am Parse-Tree vornehmen.
Warscheinlich steckt die Idee dahinter, dass die komplexe Optimierungen eher fehlerhaft sind, als einfache. In der Praxis stößt man jedoch außerst selten (wenn überhaupt jemals) auf Fehler im Compiler. Viel häufiger kommt es vor, das ein Programmierer sich nicht an die C Spezifikation gehalten hat und sein Programm nur mit Glück funktioniert. Da kann dann ein Wechsel zu einem anderen oder neueren Compiler plötzlich Probleme auslösen.
Ist vielleicht ein bisschen Off-Topic aber ich habe mir die Frage schon ein paar mal gestellt: Wie kann ein Compiler zu viel Optimieren? Die Funktion, die das Programm haben soll, beschreibe ich mit der Proframmiersprache, z.B. C. Wenn ich via SPI etwas empfange und darauf hin ein Sensor auslese, in den physikalischen Wert umrechne und zurück schicke, dann soll der Compiler das auch so umsetzen. Wenn dabei etwas nicht stimmt und der Ablauf fehlerhaft umhesetzt wird, dann mache ich nicht die Optimierung sondern den Compiler dafür verantwortlich. Er hat schließlich nicht das gemacht, was ich ihm via Sourcecode gesagt habe. Und ich denke, ich würde mich dann auch auf die Suche nach einem neuen Compiler machermachen, dessen Optimierungafunktion auch optimiert und nicht verfählscht. Kann mich da jemand erleuchten, vielleicht auch mit Beispiel?
Michael Skropski schrieb: > Kann mich da jemand erleuchten, vielleicht auch mit Beispiel? Der Forenklassiker: https://www.mikrocontroller.net/articles/Interrupt#Volatile_Variablen Der Compiler macht auch mit Optimierung praktisch immer das, was man ihm sagt. Kleine Unterschiede bestehen jedoch oft zwischen dem, was man ihm sagen wollte und was man ihm aus seiner Sicht tatsächlich gesagt hat (*). Eingeschaltete Optimierung eines gut optimierenden Compilers verschärft diesen Effekt markant. *: Wie in vielen Ehen geht es nicht zuletzt auch darum, was man alles nicht gesagt hat.
:
Bearbeitet durch User
Stefan Us schrieb: > Warscheinlich steckt die Idee dahinter, dass die komplexe Optimierungen > eher fehlerhaft sind, als einfache. Auf hohen Optimierungseinstellungen wird im Compiler selbst viel mehr Code durchlaufen, und dieser ist zusätzlich noch komplexer, und die Fehlersituationen werden subtiler. Dazu kommt dann noch, daß Optimierungen oft auch viel weniger tolerant gegen Fehler im zu übersetzenden Code sind. > In der Praxis stößt man jedoch außerst selten (wenn überhaupt jemals) > auf Fehler im Compiler. Aber wenn, dann sind es meiner Erfahrung nach am ehesten welche im Optimizer. > Viel häufiger kommt es vor, das ein Programmierer sich nicht an die C > Spezifikation gehalten hat und sein Programm nur mit Glück funktioniert. Wenn es allerdings um ein System geht, von dem Menschenleben abhängen wie der Code in einem ESP-Steuergerät oder gar einem Flugzeug-Autopilot, geht es in erster Linie darum, alles zu tun, was man kann, um Fehlfunktionen zu vermeiden und nicht nur das, was man kann, um die Schuld jemand anderem geben zu können. Im Zweifelsfall wird man das nicht mal können. Michael Skropski schrieb: > Und ich denke, ich würde mich dann auch auf die Suche nach einem neuen > Compiler machermachen, dessen Optimierungafunktion auch optimiert und > nicht verfählscht. Und woran erkennst du das, bevor so ein Fehler passiert? Ein anderer Aspekt noch: Sinnvolle Nutzung des Debuggers mit stark optimiertem Code ist je nach Compiler sehr schwer bis gar nicht möglich. Auch der generierte Assembler-Code ist nur noch schwer verständlich. Dementsprechend schwierig ist es, nachzuvollziehen, ob der generierte Assembler-Code korrekt ist.
:
Bearbeitet durch User
A. K. schrieb: > Der Forenklassiker: > https://www.mikrocontroller.net/articles/Interrupt#Volatile_Variablen Ich nehme dafür eigentlich immer globale Variablen. Find ich angenehmer, als eine Variable durch vielleicht 3 Funktionen durchzuschleifen und eben sowas wie mit interrupts zu berücksichtigen. Nebenbei find ich es auch Übersichtlicher, wenn man mit gewissen Vorgaben die Namen definiert (z.B. komplett alles Groß sind defines, g_... sind globale Variablen und der Rest nicht). Speicherplatzbedarf einer globalen Variable ist ja auch so klein es geht. Sie wird bei Funktionsübergabe ja ggf mehr mals gespeichert oder zumindest die Adresse. Die Schlüsselwörter wie static, volatile usw sollte man aber schon kennen. Doch da sehe ich die Schuld nicht beim Compiler, sondern der Programmierer hat da was vergessen. Rolf Magnus schrieb: > Und woran erkennst du das, bevor so ein Fehler passiert? Wie soll man was erkennen, was noch garnicht aufgetreten ist? Wenn ich aber sehe, dass ein Compiler nicht das umsetzt, was ich ihm wirklich gesagt habe und für die Erkenntnis vielleicht eine Woche verbracht habe, würde ich mir einen anderen Compiler suchen, denn wer sagt, dass sowas nicht nochmal vorkommt. Zudem würde ich immer im Hinterkopf überlegen "Ist das jetzt wirklich ein Fehler meines Codes oder spackt der Compiler wieder". Wenn ich jemanden überholen will und drücke aufs Gas, das Auto beschleunigt aber nicht, werde ich mich schnell nach ein anderem umsehen, am besten von einem ganz anderen Hersteller. Das Vertrauen wäre weg. Das gilt natürlich nicht, wenn ich versehentlich ein Tempolimit eingestellt habe. Mit dem Unterschied, dass da mein Leben von abhängig sein kann, beim Compiler allerdings eher nicht.
Ich bin jetzt auch mal pauschal: Optimierungen abschalten ist immer Unsinn. Ich denke, man kann nun im Prinzip zwei Szenarien unterscheiden: (1) Der Programmierer hält sich nicht an die Festlegung der Sprache. Der Optimierer verändert dann scheinbar die Semantik des Programms. Das umfasst etwa das leidliche volatile-Problem und vieles mehr. (2) Compiler und/oder Optimierer haben einen Fehler. Klar, beide sind auch nicht fehlerfrei. Gegen (1) hilft tatsächlich nur sauberes Programmieren. Man kann zwar die Optimierungen so lange frisieren, bis auch der (semantisch) fehlerhafte Programmcode (=fehlendes volatile) korrekt läuft (=Variablen nicht herausoptimieren). Und das ist auch leider gängige Praxis. Aber es ändert nichts daran, dass der Code fehlerhaft ist und etwas anderes beschreibt, als dem Programmierer vorschwebt. Früher oder später rumpelt das, pures Glücksspiel. Mit (2) dagegen muss man zuweilen rechnen. Entgegen der weit verbreiteten Meinung (MISRA..) allerdings denke ich, dass man fehler in der Compiler/Optimierer-Toolchain unter Verwendung des Optimierers soger eher finden kann: Es wird mehr Code im Compiler durchlaufen, das ist richtig und steigert die Fehlerwahrscheinlichkeit. Es wird aber auch anderer Code durchlaufen. Latente Fehler, die anfangs nicht auffallen oder nicht nachvollziehbar sind, verändern sich recht wahrscheinlich, wenn der Optimierer mitarbeitet. Grundsätzlich halte ich schließlich die Argumentation gegen den Optimierer von wegen "da wird mehr und komplexerer Code durchlaufen" für fragwürdig. Daran die Sicherheit eines Systemes zu bewerten ist grob fahrlässig. Woran bemisst man das denn? Dann dürfte man ja konsequenterweise auch irgendwann keine neuen Compilerversionen mehr verwenden, weil die durchlaufen auch immer mehr Code. Von Hardwaresynthese mal ganz zu schweigen...
Nase schrieb: > Dann dürfte man ja > konsequenterweise auch irgendwann keine neuen Compilerversionen mehr > verwenden, weil die durchlaufen auch immer mehr Code. Betriebsbewährtheit ist tatsächlich ein Thema, und neue Compilerversionen in der Zulassungspraxis auch problematisch.
Michael Skropski schrieb: > Wie kann ein Compiler zu viel Optimieren? Die Funktion, die das Programm > haben soll, beschreibe ich mit der Proframmiersprache, z.B. C. Wenn ich > via SPI etwas empfange und darauf hin ein Sensor auslese, in den > physikalischen Wert umrechne und zurück schicke, dann soll der Compiler > das auch so umsetzen. Häufig verlassen sich Leute auf bestimmtes Übersetzungsverhalten des Compilers, auch wenn das nirgendwo im C-Standard spezifiziert ist (undefined behavior!). Gerade bei höheren Optimierungsstufen knallt es dann gerne. Wenn ein Programm nur mit -O0 funktioniert und selbst mit -O1 dann nicht mehr, weist es i.d.R. auf einen Fehler im Code hin, nicht auf einen Fehler des Compilers!
Freddie schrieb: > Betriebsbewährtheit ist tatsächlich ein Thema, und neue > Compilerversionen in der Zulassungspraxis auch problematisch. Und selbst Bewährtheit ist hier eigentlich ein ganz schön schwaches Argument.
Fpga Kuechle schrieb: > bin ich über den Punkt > gestolpert, das verschiedenen Standards/Zertifizierungen ( im > embedded-bereich) verlangen das die maschinelle Optimierung > auszuschalten ist (cc -O0). Das ist ein Widerspruch in sich: In diesen Umfeldern wird gerne auf "zertifizierte" Compiler bestanden. Das impliziert daß diese vollumfänglich getestet sind und für funktionierend befunden wurden. Die Forderung dann trotzdem auf gewisse Optionen dieser "zertifizierten" Compiler zu verzichten impliziert daß diese wohl anscheinend doch fehlerhaft sein könnten, mithin man sich also den ganzen Zertifizierungs-Schmu ebensogut getrost in die Haare hätte schmieren können. Jedoch verdienen etablierte Hersteller ordentlich Geld mit dieser Kultur der gegenseitigen Beweihräucherung in geschlossener Gesellschaft, völlig losgelöst vom praktischen Nutzwert oder irgendeiner Logik, daher ist das nun mal einfach so und daran wird auch nicht gerüttelt. Ich als Normalsterblicher nehme gcc und die üblichen Optimierungen, denn zum Glück schreibt mir hier keiner vor welche (womöglich suboptimalen) Werkzeuge und Einstellungen angeblich besser sein sollen nur weil sie in irgendeinem teuren Papier erwähnt werden, ich wähle sie stattdessen nach objektiven Kriterien der praktischen Tauglichkeit für den jeweiligen Verwendungszweck aus.
Michael Skropski schrieb: > A. K. schrieb: >> Der Forenklassiker: >> https://www.mikrocontroller.net/articles/Interrupt#Volatile_Variablen > > Ich nehme dafür eigentlich immer globale Variablen. Find ich angenehmer, > als eine Variable durch vielleicht 3 Funktionen durchzuschleifen und > eben sowas wie mit interrupts zu berücksichtigen. > > Die Schlüsselwörter wie static, volatile usw sollte man aber schon > kennen. Doch da sehe ich die Schuld nicht beim Compiler, sondern der > Programmierer hat da was vergessen. Kleiner Hinweis am Rande, wenn du globale Variablen zur Kommunikation mit Interrupts nutzt und die nicht volatile sind, ist es reines Glück, dass das funktioniert. volatile hat nämlich mit dem Scope einer Variablen rein gar nix zu tun.
Stefan Us schrieb: > Warscheinlich steckt die Idee dahinter, dass die komplexe Optimierungen > eher fehlerhaft sind, als einfache. Nein, IMHO geht es weniger um Fehler als darum das der Compiler die im Quelltext beschrieben Funktion in eine andere überführt als die verifiziert wurde. Ergebnis der Zertifizierung soll die Sicherstellung sein das die Software das tut was sie soll und nie was anderes machen kann. (auch wenn das andere ergebnismäßig gleich wäre). Diese Überprüfung geschieht nun am C-Code, da Assembler oder Hexcode zu kryptisch und zu lang sind als das man ihn 100% verifizieren kann. Man will ja auch die Funktion überprüfen und geht dann davon aus das die 1:1 Umsetzung des Compilers passt. Und um den c-code einfach prüfbar zu halten, schränkt man den noch ein (MISRA-C), es darf nicht jedes C-konstrukt verwendet werden. Beispielscenario: loop-unrolling. Jetz hat man den Code zertififiziert, Programmzeilen gezählt und abgeschätzt das es so in den Speicher passt. Da kommt der Compiler daher und optimiert den code durch loop unrooling, er spart sich das dekrement des loop-index, den Vergleich und die pipelinestörende Springerei, der code ist schneller, länger und passt immer noch in den Speicher. Klingt erst mal so also ob nix wesentliches verändert wurde. Nun sei der Speicher aus mehrerern Speicher-modulen/IC aufgebaut. Und man hat aufgepasst das wenn ein beliebiges Modul ausfällt, oder aus Stromspargründen (Space) abgeschaltet wird, nichts schlimmes passiert. Allerdings in der Annahme das die besagte Schleife sich in einem Speichermodul komplett befindet und nicht wie durch das loop-unrooling mglw. geschehen in zwei. Dumm gelaufen oder dumm gemacht? MfG,
Bernd K. schrieb: > Fpga Kuechle schrieb: >> bin ich über den Punkt >> gestolpert, das verschiedenen Standards/Zertifizierungen ( im >> embedded-bereich) verlangen das die maschinelle Optimierung >> auszuschalten ist (cc -O0). > > Das ist ein Widerspruch in sich: In diesen Umfeldern wird gerne auf > "zertifizierte" Compiler bestanden. Das impliziert daß diese > vollumfänglich getestet sind und für funktionierend befunden wurden. Nein, es sind nicht die Überstzungsfehler die man fürchtet sondern man spart sich die Arbeit für jeden compiler und Optimierungsstufe zu überprüfen ob aus dem C-Code den man gecheckt hat auch was erzeugt wird das wiederum OK ist. Bei Optimierung kommt nun mal anderer Code raus also andere Speicherbelgung/Laufzeit als ohne Optimierung. > Die > Forderung dann trotzdem auf gewisse Optionen dieser "zertifizierten" > Compiler zu verzichten impliziert daß diese wohl anscheinend doch > fehlerhaft sein könnten, mithin man sich also den ganzen > Zertifizierungs-Schmu ebensogut getrost in die Haare hätte schmieren > können. Hm, das könnte womöglich sein, wobei es dann nicht Compilerzertifizierung an sich unnötig ist sondern nur die Zertifizierung der Optimierung. Und die Optimierung wäre ebenfalls unnötig. Wäre nicht das erste mal das Compiler feature enthalten die man eigentlich nicht will. Aber dann hätte man kein Verkaufsargument um sich vom gcc und Mitbewerber abzusetzen. MfG,
Fpga Kuechle schrieb: > Allerdings in der Annahme das die besagte Schleife sich in einem > Speichermodul komplett befindet und nicht wie durch das loop-unrooling > mglw. geschehen in zwei. > Dumm gelaufen oder dumm gemacht? Hallelujah... das dem Compiler ist die Schuhe zu schieben ist schon reichlich vermessen. Bei solcher Auslegung musst du auch bei Assembler-Programmierung nach wesentlichen Änderungen das Mapfile bemühen. Insbesondere wenn du nicht alleim am Projekt hockst. Ausserdem pflegen Compiler auch morgen noch den gleichen Code zu erzeugen wie heute, wenn man weder das eigene Programm noch den Compiler aktualisiert. Und wenn man eine derart empfindliche Umgebung hat, dann gehört man doch geteert und gefedert, wenn man den Compiler updatet. Die verwendete Compiler-Version sollte als Teil einer isolierten Entwicklungsumgebung für genau dieses Projekt auf alle Zeit eingefroren werden.
:
Bearbeitet durch User
Fpga Kuechle schrieb: > Allerdings in der Annahme das die besagte Schleife sich in einem > Speichermodul komplett befindet und nicht wie durch das loop-unrooling > mglw. geschehen in zwei. Wer solche Annahmen trifft und glaubt sich darauf verlassen zu können und die Betriebssicherheit seines Systems von solchen wackeligen Annahmen abhängig macht und das dann obendrein auch noch mit den Begriffen "reproduzierbar" oder gar "zertifiziert" in Zusammenhang bringt der verdient daß es ihm bei der nächsten Gelegenheit um die Ohren fliegt, aber sowas von.
Fpga Kuechle schrieb: > Ergebnis der Zertifizierung soll die Sicherstellung sein das die > Software das tut was sie soll und nie was anderes machen kann. (auch > wenn das andere ergebnismäßig gleich wäre). Diese Überprüfung geschieht > nun am C-Code, da Assembler oder Hexcode zu kryptisch und zu lang sind > als das man ihn 100% verifizieren kann. Das ist jetzt aber ein Widerspruch in sich. Bei einer solchen (hanebüchen) Zertifizierung bewertet man doch genau das Ergebnis, das die Software produziert. Und das ist stets dasselbe, egal wie optimiert wird. Andernfalls müsste man ja gerade das Assembly zertifizieren. > Man will ja auch die Funktion > überprüfen und geht dann davon aus das die 1:1 Umsetzung des Compilers > passt. Welche 1:1-Umsetzung denn? Ein C-Compiler ist kein Makroassembler. Es gibt keine 1:1-Umsetzung. > Und um den c-code einfach prüfbar zu halten, schränkt man den noch ein > (MISRA-C), es darf nicht jedes C-konstrukt verwendet werden. Ja, MISRA ist eben in vielen Dingen Schwachsinn. Quelltext wird nicht sicherer, wenn man dem Programmierer Sprachfeatures verbietet, die er dann möglicherweise mit noch mehr Gebastel wieder umgeht. > Beispielscenario: loop-unrolling. > > Jetz hat man den Code zertififiziert, Programmzeilen gezählt und > abgeschätzt das es so in den Speicher passt. Ok, schon der falsche Ansatz. Aber gut, wers braucht. > Da kommt der Compiler daher > und optimiert den code durch loop unrooling, er spart sich das dekrement > des loop-index, den Vergleich und die pipelinestörende Springerei, der > code ist schneller, länger und passt immer noch in den Speicher. Klingt > erst mal so also ob nix wesentliches verändert wurde. Wurde es ja auch nicht. Die Programmiersprache C wird anhand eines abstrakten Automaten mit Seiteneffekten definiert. Jeder, der darin irgendetwas Anderes sieht, sollte C nicht verwenden. > Nun sei der Speicher aus mehrerern Speicher-modulen/IC aufgebaut. Und > man hat aufgepasst das wenn ein beliebiges Modul ausfällt, oder aus > Stromspargründen (Space) abgeschaltet wird, nichts schlimmes passiert. > Allerdings in der Annahme das die besagte Schleife sich in einem > Speichermodul komplett befindet und nicht wie durch das loop-unrooling > mglw. geschehen in zwei. > > Dumm gelaufen oder dumm gemacht? Extrem dumm gemacht. Insbesondere bei relokatierenden Linkern, wie gcc einer ist. Wenn du sicherstellen musst, dass ein Stück Quelltext an einer besonderen Stelle landet, dann solltest du das im Linkerskript festlegen. Alles andere ist wieder Glücksspiel.
Meiner Meinung nach, ist MISRA nur ein äußerst schwaches Werkzeug, um zuverlässige Programme zu erstellen. Es ist sehr leicht, MISRA konform zu programmieren und trotzdem tonnenweise logische Fehler einzubauen. Z.B. das in MISRA verbotene ?: hat überhaupt kein Fehlerpotential. Im Gegenteil, es erlaubt sehr sicheren (Sequence point!) und gut lesbaren Code. Es wurde nur verbannt, weil es Anfänger erstmal nachschlagen müßten. Das wichtigste ist, daß man erstmal reichlich Programmiererfahrung bei nicht kritischen Anwendungen (Eieruhr, Tamagotchi usw.) gesammelt hat. Diese sind durch keine noch so strengen Formalismen zu ersetzen. Wer Anfänger an sicherheitsrelevanten Code ranläßt, ist automatisch Hauptschuldiger am z.B. Flugzeugabsturz oder AKW-Gau.
Michael Skropski schrieb: > Rolf Magnus schrieb: >> Und woran erkennst du das, bevor so ein Fehler passiert? > > Wie soll man was erkennen, was noch garnicht aufgetreten ist? Gar nicht. Das war mein Punkt. Du sagst, daß du beim Auftreten eines Compilerfehlers sofort zu einem anderen, fehlerfreien Compiler wechseln würdest. Woher weißt du aber, daß der fehlerfrei ist? > Wenn ich aber sehe, dass ein Compiler nicht das umsetzt, was ich ihm > wirklich gesagt habe und für die Erkenntnis vielleicht eine Woche > verbracht habe, würde ich mir einen anderen Compiler suchen, denn wer > sagt, dass sowas nicht nochmal vorkommt. Wer sagt, daß es bei einem anderen Compiler nicht auch vorkommt? Der könnte sogar noch mehr Fehler haben als der voherige. Einfach gleich beim ersten Fehler wild durchwechseln ist ziemlich unsinnig. Oder kurz: Du tauschst bekannte Fehler gegen unbekannte. Deshalb wird in Bereichen, wo der Code sicher sein muß, nicht einfach mal schnell der Compiler gewechselt, auch nicht bei einem Bug im Compiler. > Wenn ich jemanden überholen will und drücke aufs Gas, das Auto > beschleunigt aber nicht, werde ich mich schnell nach ein anderem > umsehen, am besten von einem ganz anderen Hersteller. Ich nicht. Tatsächlich hatte ich diesen Fall schon mal. Das war eben ein Defekt am Motor. Aber ich kauf mir nicht bei jede, Fehler ein neues Auto. Abgesehen davon würden einem in so einem Fall irgendwann die Hersteller ausgehen. > Das Vertrauen wäre weg. Das gilt natürlich nicht, wenn ich versehentlich > ein Tempolimit eingestellt habe. Mit dem Unterschied, dass da mein Leben > von abhängig sein kann, beim Compiler allerdings eher nicht. Vielleicht nicht bei dem Code den du schreibst, aber bei dem Code, um den es in den hier diskutierten Sicherheitsnormen geht. Sehr viele moderne Autos haben zB. E-Gas, d.h. es geht kein Gazsug mehr vom Pedal zum Motor, sondern C-Code auf deinem Steuergerät (entweder von Hand geschrieben oder aus einem Modell generiert) interpretiert die Pedalstellung und entscheidet dann, wieviel Leistung er dem Motor abverlangt. Der kann bei einem Fehler auch entscheiden, dir keine Motorleistung zu geben, wenn du auf's Gas trittst. Nase schrieb: > Gegen (1) hilft tatsächlich nur sauberes Programmieren. Man kann zwar > die Optimierungen so lange frisieren, bis auch der (semantisch) > fehlerhafte Programmcode (=fehlendes volatile) korrekt läuft (=Variablen > nicht herausoptimieren). Und das ist auch leider gängige Praxis. Aber es > ändert nichts daran, dass der Code fehlerhaft ist und etwas anderes > beschreibt, als dem Programmierer vorschwebt. Früher oder später rumpelt > das, pures Glücksspiel. Es geht eher darum, daß der Code zwar zu funktionieren scheint, man aber ein Fehlverhalten trotz Coding-Richtlinien, Reviews und enormen Testaufwands nicht gänzlich ausschließen kann. Dessen Wahrscheinlichkeit verringert man durch das Abschalten der Optimierungen noch. Ein Fallschirmspringer hat ja auch noch einen Not-Schirm dabei, obwohl am Hauptschirm ja eigentlich nichts sein dürfte. drama schrieb: > Wenn ein Programm nur mit -O0 funktioniert und selbst mit -O1 dann nicht > mehr, weist es i.d.R. auf einen Fehler im Code hin, nicht auf einen > Fehler des Compilers! Wenn dein Auto in eine Wand rast, weil das ESP eine Fehlfunktion hat, ist dir allerdings relativ egal, ob das durch einen Bug im Compiler oder im durch ihn übersetzten Programm passiert ist. Du hättest dir dann eher gewünscht, daß an jedem Teil der Kette alles getan worden wäre, um ein Fehlverhalten zu vermeiden. Bernd K. schrieb: > Das ist ein Widerspruch in sich: In diesen Umfeldern wird gerne auf > "zertifizierte" Compiler bestanden. Das impliziert daß diese > vollumfänglich getestet sind und für funktionierend befunden wurden. Wenn ein Compiler zertifiziert ist, ist er damit nicht automatisch fehlerfrei. Es wurde lediglich bestätigt, dass Entwicklung und Test (teils sehr aufwändig) nach bestimmten Richtlinien erfolgt ist, durch die viele Fehler (vermeintlich) vermieden werden können. > Jedoch verdienen etablierte Hersteller ordentlich Geld mit dieser Kultur > der gegenseitigen Beweihräucherung in geschlossener Gesellschaft, völlig > losgelöst vom praktischen Nutzwert oder irgendeiner Logik, daher ist das > nun mal einfach so und daran wird auch nicht gerüttelt. Du würdest also sagen, das das Steuersystem im A380 auch ruhig mit einem Compiler übersetzt werden kann, der von irgendeiner Hinterhofklitsche geschrieben wurde? Bei dem hat man übrigens sogar Hard- und Software zweimal entwickeln lassen, von verschiedenen Herstellern, mit verschiedenen Komponenten und verschiedenen Entwicklungstoolchains, alles zertifiziert. > Ich als Normalsterblicher nehme gcc und die üblichen Optimierungen, denn > zum Glück schreibt mir hier keiner vor welche (womöglich suboptimalen) > Werkzeuge und Einstellungen angeblich besser sein sollen nur weil sie in > irgendeinem teuren Papier erwähnt werden, ich wähle sie stattdessen nach > objektiven Kriterien der praktischen Tauglichkeit für den jeweiligen > Verwendungszweck aus. Dein Verwendungszweck ist eben ein anderer. Wie würdest du das denn sehen, wenn du den Code für dein ESP damit übersetzen müßtest? Lieber besser optimieren, damit der Prozessor vielleicht eine nummer kleiner ausfallen kann, oder lieber sicherer? A. K. schrieb: > Fpga Kuechle schrieb: >> Allerdings in der Annahme das die besagte Schleife sich in einem >> Speichermodul komplett befindet und nicht wie durch das loop-unrooling >> mglw. geschehen in zwei. > >> Dumm gelaufen oder dumm gemacht? > > Hallelujah... das dem Compiler ist die Schuhe zu schieben ist schon > reichlich vermessen. Das hat doch keiner getan. > Ausserdem pflegen Compiler auch morgen noch den gleichen Code zu > erzeugen wie heute, wenn man weder das eigene Programm noch den Compiler > aktualisiert. Da gibt's grad einen Thread im Forum, der sich damit beschäftigt, daß das nicht stimmt. Interessanterweise gibt es offenbar gerade im Optimizer von gcc sogar einen Teil, der für die Optimierung einen Zufallsgenerator verwendet.
Fpga Kuechle schrieb: > Stefan Us schrieb: >> Warscheinlich steckt die Idee dahinter, dass die komplexe Optimierungen >> eher fehlerhaft sind, als einfache. > > Nein, IMHO geht es weniger um Fehler als darum das der Compiler die im > Quelltext beschrieben Funktion in eine andere überführt als die > verifiziert wurde. Ich weiß es selber zwar auch nicht besser, aber Stefans Erklärung erscheint mir irgendwie plausibler: Wenn ein Teil (Optimierer) eines komplexen Programms (Compiler) nicht genutzt wird, werden auch dessen Fehler nicht wirksam. > Ergebnis der Zertifizierung soll die Sicherstellung sein das die > Software das tut was sie soll und nie was anderes machen kann. Mikroskopisch betrachtet tut die kompilierte Software doch fast immer etwas anderes als im Quelltext steht, weil C-Anweisungen in den allermeisten Fällen nicht 1:1 auf Prozessorinstruktionen abbildbar sind. So werden bspw. auf einem 8-Bit-Prozessor aus 1 long-Addition in C 4 Byte-Additionen im erzeugten Maschinencode. > (auch wenn das andere ergebnismäßig gleich wäre). Wenn die Ergebnisse ohne und mit Optimierung immer gleich sind, ist doch alles in Ordnung. Wenn nicht, hat entweder der Programmierer oder der Optimierer einen Fehler gemacht. Der zweite Fall könnte durch Weglassen der Optimierungsphase ausgeschlossen werden. Da der erste aber um Größenordnungen wahrscheinlicher ist, bringt das nicht sehr viel ;-) > Beispielscenario: loop-unrolling. > > ... > > Nun sei der Speicher aus mehrerern Speicher-modulen/IC aufgebaut. Und > man hat aufgepasst das wenn ein beliebiges Modul ausfällt, oder aus > Stromspargründen (Space) abgeschaltet wird, nichts schlimmes passiert. > Allerdings in der Annahme das die besagte Schleife sich in einem > Speichermodul komplett befindet und nicht wie durch das loop-unrooling > mglw. geschehen in zwei. Man kann aber auch ohne Loop-Unrolling nicht verhindern, dass die Schleife an einer Speichermodulgrenze zu liegen kommt, auch wenn die Wahrscheinlichkeit dafür kleiner ist als mit Loop-Unrolling. Zudem wird die Schleife meist ja irgendwann wieder verlassen. Spätestens dann wird das Programm trotzdem in das ausgeschaltete/-fallene Modul hineinlaufen. Es sei denn, das Programm ist insgesamt so kurz, dass es in ein einzelnes Speichermodul passt. Das erreicht man aber am ehesten dadurch, dass man die Optimierung der Programmgröße (beim GCC -Os) nicht aus-, sondern einschaltet. Bernd K. schrieb: > Das ist ein Widerspruch in sich: In diesen Umfeldern wird gerne auf > "zertifizierte" Compiler bestanden. Das impliziert daß diese > vollumfänglich getestet sind und für funktionierend befunden wurden. Das erhofft sich der Kunde, der viel Geld für so einen Compiler ausgibt. Tatsächlich heißt Sicherheitszertifizierung bei Compilern zunächst einmal nur, dass sie von einer unabhängigen Organisation (wie bspw. dem TÜV) auf Konformität zu einem oder mehreren der einschlägigen Sicherheitsstandards (IEC 61508, ISO 26262, ISO 26262 usw.) sind, wie dies bspw. bei den IAR-Tools der Fall ist: http://www.iar.com/Products/IAR-Embedded-Workbench/Certified-tools-for-functional-safety/Functional-safety-standards/ M.W. legt aber keine der o.g. Normen ein genaues Regelwerk fest, wie ein Compiler zu prüfen ist, um dessen Konformität festzustellen, da sie sich ja nicht auf Compiler im Speziellen, sondern auf Systeme und und deren Software im Allgemeinen beziehen. Der folgende Artikel gibt einen groben Einblick in diese Problematik: http://www.embedded.com/design/prototyping-and-development/4007228/How-to-verify-your-compiler-for-use-in-IEC-61508-safety-critical-applications Die wesentlichen Punkte, die ich daraus entnehme: - Die Softwareentwicklung muss nach bestimmten Prozessen ablaufen, wozu insbesondere auch eine durchgehende Dokumentation dieser Prozesse gehört. Das hilft immerhin dazu bei, im Fehlerfall den Verursacher an den Pranger stellen zu können. Vielleicht erhöht das deswegen auch etwas die Sorgfalt bei der Entwicklung. - Es gibt Empfehlungen, die nach Möglichkeit einzuhalten sind. Sind diese Empfehlungen aus irgendwelchen Gründen nicht praktikabel, darf auch davon abgewichen werden, wenn diese Abweichungen ausreichend begründet und dokumentiert werden. Eine solche Abweichung ist bspw. schon die Verwendung von C als Programmiersprache: Die allermeisten C-Compiler sind nun einmal in C geschrieben und die damit entwickelte sicherheitskritische Software logischerweise ebenso. - Da die korrekte Arbeitsweise des Compilers kaum formal verfiziert werden kann, muss sie auf andere Weise ausreichend begründet werden. Die Begründung ist dann in Ordnung, wenn sie vom Prüfer akzeptiert wird. In dem Artikel wird u.a. "proof-in-use" vorgschlagen, d.h. ein länger andauernder fehlerfreier Einsatz des Compilers (oder allgemein die sicherheitskritische Software) bei vielen Nutzern wird als Indiz für hohe Sicherheit gewertet. Es gibt sicher noch mehr Kriterien, die von einem zertifizierten Compiler erfüllt sein müssen. Ich frage mich allerdings, ob das alles ausreicht, um diesen wirklich sicherer zu machen als bspw. den GCC. Nimmt man von diesem das jeweils neueste Release des zweitneuesten (und damit schon etwas gereiften) Branches (derzeit wäre das die Version 4.8.4), ist dank der weiten Verbreitung des GCC und der Unmengen an Software, die damit bereits kompiliert worden ist, der "proof-in-use" sicher schon deutlich stärker gegeben als bei einem zertifizierten Compiler, der auf Grund seines hohen Preises nur von relativ wenigen Anwendern eingesetzt wird. Interessant wäre es ja, den Prüfbericht eines zertifizierten Compilers durchzulesen, um genauer zu erfahren, nach welchen Kriteren da konkret bewertet wurde. Weiß jemand, ob man als (bspw. IAR-) Kunde Einblick in einen solchen Bericht bekommt?
Bernd K. schrieb: > Fpga Kuechle schrieb: >> Allerdings in der Annahme das die besagte Schleife sich in einem >> Speichermodul komplett befindet und nicht wie durch das loop-unrooling >> mglw. geschehen in zwei. > > Wer solche Annahmen trifft und glaubt sich darauf verlassen zu können > und die Betriebssicherheit seines Systems von solchen wackeligen > Annahmen abhängig macht und das dann obendrein auch noch mit den > Begriffen "reproduzierbar" oder gar "zertifiziert" in Zusammenhang > bringt der verdient daß es ihm bei der nächsten Gelegenheit um die Ohren > fliegt, aber sowas von. Den Grund für deine drastischen Worte versteh ich nicht. Das ist hier nur ein beispiel das sich Optimierungen auf die Fehlercharakteristik des systems auswirken. das ein system von grund auf sicher ist wenn loop-unrolling deaktiviert ist habe ich nie behauptet. Von reproduzierbar war auch nicht die Rede. Also bitte mehr sachlichkeit. MfG,
Yalu X. schrieb: >> Nun sei der Speicher aus mehrerern Speicher-modulen/IC aufgebaut. Und >> man hat aufgepasst das wenn ein beliebiges Modul ausfällt, oder aus >> Stromspargründen (Space) abgeschaltet wird, nichts schlimmes passiert. >> Allerdings in der Annahme das die besagte Schleife sich in einem >> Speichermodul komplett befindet und nicht wie durch das loop-unrooling >> mglw. geschehen in zwei. > > Man kann aber auch ohne Loop-Unrolling nicht verhindern, dass die > Schleife an einer Speichermodulgrenze zu liegen kommt, auch wenn die > Wahrscheinlichkeit dafür kleiner ist als mit Loop-Unrolling. Zudem wird > die Schleife meist ja irgendwann wieder verlassen. Spätestens dann wird > das Programm trotzdem in das ausgeschaltete/-fallene Modul hineinlaufen. > Es sei denn, das Programm ist insgesamt so kurz, dass es in ein > einzelnes Speichermodul passt. Loop unrolling ist ja hier nur ein Beispiel das man Eigenschaften die man aus dem C-Quelltext zieht nicht mehr auf das Compilat zutreffen > Das erreicht man aber am ehesten dadurch, > dass man die Optimierung der Programmgröße (beim GCC -Os) nicht aus-, > sondern einschaltet. Dann verste ich das Optimierungskonzept anders, also wenn Optimierung aus -O0 wird dennoch loop-unrolling betrieben? Bei Sizeoptimierung bleibt es im wesentlichen bei dem selben Problem: Eigenschaften die aus dem Quelltext gezogen werden wie Größe Daten/Codesegment stimmen nicht mit dem Kompilat überein, beispielsweise Strings zusammenfassen. const char[] str_message_ok "KEIN FEHLER"; const char[] str_message_nok "EIN FEHLER"; Zertifizierung funktioniert eben leider indirekt. Es sollen Eigenschaften des Programm als das binary bewertet werden. Betrachtet wird aber der Quelltext. Also muß man dem Compiler alle Freiheitsgrade nehmen damit er den code 1:1 übersetzt. MfG,
A. K. schrieb: > Fpga Kuechle schrieb: >> Allerdings in der Annahme das die besagte Schleife sich in einem >> Speichermodul komplett befindet und nicht wie durch das loop-unrooling >> mglw. geschehen in zwei. > >> Dumm gelaufen oder dumm gemacht? > > Hallelujah... das dem Compiler ist die Schuhe zu schieben ist schon > reichlich vermessen. Nee, ich sach nich der Compiler is schuld. Schuld ist das prinzip das Programm anhand seines Sources zu Prüfen und nicht am Compilat. Und das ist auch kein Fehler sondern eine Frage der Machbarkeit. Am Compilat die Fehlerfrfeiheit zu prüfen ist IMHO hoffnungsloser als die Prüfung am C-Quelltext. > Bei solcher Auslegung musst du auch bei > Assembler-Programmierung nach wesentlichen Änderungen das Mapfile > bemühen. Insbesondere wenn du nicht alleim am Projekt hockst. Ist Begutachtung des Map-files Bestandteil der Zertifizierung? Ist der Compiler/Assembler bezüglich des Wahrheitsgehaltes seines map- reports zertifiziert? > > Ausserdem pflegen Compiler auch morgen noch den gleichen Code zu > erzeugen wie heute, wenn man weder das eigene Programm noch den Compiler > aktualisiert. Und wenn man eine derart empfindliche Umgebung hat, dann > gehört man doch geteert und gefedert, wenn man den Compiler updatet. Die > verwendete Compiler-Version sollte als Teil einer isolierten > Entwicklungsumgebung für genau dieses Projekt auf alle Zeit eingefroren > werden. Volle Zustimmung. MfG,
Fpga Kuechle schrieb: > Ist Begutachtung des Map-files Bestandteil der Zertifizierung? Ich habe keine Ahnung von solchen Zertifizierungen. Aber mit Zertifizerungen kann man kein Hirn ersetzen. Wenn eine strikte Adressvergabepolitik Teil der Anwendung ist, dann muss eine Kontrolle der Adressvergabe Teil der Entwicklung sein. Notfalls per Kontrollprogramm, dass an deiner Statt ins Mapfile guckt, oder wasweissich wohin. Unabhängig von irgendwelchen offiziellen Stempeln.
:
Bearbeitet durch User
Yalu X. schrieb: > Interessant wäre es ja, den Prüfbericht eines zertifizierten Compilers > durchzulesen, um genauer zu erfahren, nach welchen Kriteren da konkret > bewertet wurde. Weiß jemand, ob man als (bspw. IAR-) Kunde Einblick in > einen solchen Bericht bekommt? Da wüsst ich auch gern. Mir ist ein Fall bekannt in dem der Hersteller dem Kunden angeboten hat die CPU und Compiler gemeinsam zu zertifizieren, wenn sich der Kunde für diese CPU entscheidet. Hat man aber nicht, also war auch nix mit Zertifizierung. Der Kunde war R&S, zertifiziert werden sollte nach DO-178 o.ä.. MfG,
Rolf Magnus schrieb: > Es geht eher darum, daß der Code zwar zu funktionieren scheint, man aber > ein Fehlverhalten trotz Coding-Richtlinien, Reviews und enormen > Testaufwands nicht gänzlich ausschließen kann. Dessen Wahrscheinlichkeit > verringert man durch das Abschalten der Optimierungen noch. > Ein Fallschirmspringer hat ja auch noch einen Not-Schirm dabei, obwohl > am Hauptschirm ja eigentlich nichts sein dürfte. Nein, überhaupt nicht. Eher im Gegenteil: Durch Optimierungen fallen Fehler eher auf. Ganz einfach, weil das, was man hinprogrammiert hat, quasi aus unterschiedlichen Blickwinkeln übersetzt wird. Wenn mit Optimierung "1" läuft und mit Optimierung "2" nicht mehr, dann sucht man mit sehr großer Wahrscheinlichkeit ein latentes Problem in seiner Anwendung. Deine Argumentation könnte man ja genauso auch so lesen: Der Optimierer verringert das erzeugte Codevolumen (erheblich). Also wird auch weniger Code ausgeführt, der Fehler haben könnte... Rolf Magnus schrieb: > Du würdest also sagen, das das Steuersystem im A380 auch ruhig mit einem > Compiler übersetzt werden kann, der von irgendeiner Hinterhofklitsche > geschrieben wurde? Nein, sicher will er das nicht. Er will nur sagen, dass solche Zertifizierungen objektiv ziemlich grenzwertig sind. Auch meine Meinung ist, dass solch eine Zertifizierung kurz über Antivirenprogrammen rangiert. Wie soll man einen Compiler denn auch zertifizieren? Oder was soll man überhaupt zertifizieren? Den Quelltext des Compilers wird man ganz sicher nicht verifizieren können, schon aufgrund seines Umfangs. Also bleibt nur, etwas Testcode reinzustecken und zu gucken, was herauskommt. Also im Prinzip etwas total praxisfernes für einen Einzelfall zu machen und einen Stempel dranzumachen. Das ist ungefähr so, wie einen Compiler mit einer Endlosschleife zu benchmarken. Der Internet-Explorer ist auch TÜV-Zertifiziert. Auf Heise-Newsticker damals stand die Meldung von der Zertifizierung des IE gleich unter einer neuen Sicherheitslücke im IE. > Bei dem hat man übrigens sogar Hard- und Software zweimal entwickeln > lassen, von verschiedenen Herstellern, mit verschiedenen Komponenten und > verschiedenen Entwicklungstoolchains, alles zertifiziert. Und solche Diversität ist m.M.n. der einzig tragbare Ausweg aus dem Dilemma. Das macht jede Sicherheitssteuerung heute so. Rolf Magnus schrieb: > Dein Verwendungszweck ist eben ein anderer. Wie würdest du das denn > sehen, wenn du den Code für dein ESP damit übersetzen müßtest? Lieber > besser optimieren, damit der Prozessor vielleicht eine nummer kleiner > ausfallen kann, oder lieber sicherer? Auch das basiert wieder auf der fragwürdigen Annahme, dass ein Optimierer den Code potentiell fehlerträchtiger macht. Wenn ich etwas für ein ESP übersetzen müsste, dann würde ich mir alle greifbaren Compiler für die Zielarchitektur nehmen und den Quelltext in allen Compilern mit allen Optimierungsstufen (oder sonstigen Einstellungen derart) testen. Damit finde ich mehr Fehler, als den Optimierer pauschal abzustellen. Der Optimierer ist ja auch nur ein kleiner Teil. Würdest du deinen Quelltext dann auch nicht modulweise übersetzen, sondern alles zusammenkopieren? Linker und Präprozessor können auch Fehler machen. Yalu X. schrieb: > Mikroskopisch betrachtet tut die kompilierte Software doch fast immer > etwas anderes als im Quelltext steht, weil C-Anweisungen in den > allermeisten Fällen nicht 1:1 auf Prozessorinstruktionen abbildbar sind. Du brauchst soweit garnicht zu gehen. Das ist die abstrakte Maschine, die ich oben erwähnte. Als Beispiel folgende beiden Programmstücke:
1 | fputs("abc", stdout); |
und
1 | putchar('a'); |
2 | putchar('b'); |
3 | putchar('c'); |
Wie bewertest du die nun? Strenggenommen könnte der Compiler aus beiden Programmen denselben Maschinencode erzeugen. Denn beide Programme verhalten sich exakt identisch. Das liegt eben daran, dass die Sprache C anhand einer abstrakten Maschine definiert ist und ihr Verhalten sich in der Wirkung nach außen manifestiert. Beide obigen Programme geben 'abc' aus. Wie der Compiler das bewerkstelligt, ist ihm überlassen. Er könnte die drei putchar-Aufrufe legitim zu einem fputs-Aufruf zusammenziehen, ohne das Programm zu verändern. Das ist im Übrigen dann auch das Problem der meisten Anwendungen. Damit ich mit dieser Sprachdefinition klarkomme, müssen fputs und putchar natürlich hinreichend eintrittsinvariant, also frei von Seiteneffekten sein (was sie laut Standard auch sind). Code in Applikationen ist das oft nicht. Yalu X. schrieb: > Weiß jemand, ob man als (bspw. IAR-) Kunde Einblick in > einen solchen Bericht bekommt? Papier ist geduldig. Fpga Kuechle schrieb: > Den Grund für deine drastischen Worte versteh ich nicht. Das ist hier > nur ein beispiel das sich Optimierungen auf die Fehlercharakteristik des > systems auswirken. Naja, er hat ein drastisches Problem bemängelt. Dein Beispiel scheitert nicht ander Fehlercharakteristik des Systems, sondern schon einfach an der Fehlbedienung der Toolchain. Wenn irgendetwas dafür verantwortlich ist, wo Code landet, dann /ganz sicher nicht/ der Optimierer. Die Optimierungen abzuschalten sind ein primitives Mittel, um einen besseren Zusammenhang zwischen Quelltext und Assembly hinzubekommen. Darum möchte man beim Debuggen ja auch nicht optimieren, weil man dann nur schwer Zeile für Zeile durchschreiten kann. Aber Optimierungen abzuschalten ist definitiv das falsche Mittel, um Code im Speicher zu platzieren - dafür ist der Linker verantwortlich. Leider sieht man das halt oft: Die Programmierer wissen nichts über volatile oder sind zu bequem, also schaltet man pauschal die Optimierung aus... Letztlich bleibt die wesentliche Frage, ob man pauschal Fehler vermeidet, wenn man Teile des Compilers (den Optimierer) nicht nutzt und so weniger Code im Compiler beansprucht. Ich denke nach wie vor: Nein.
Rolf Magnus schrieb: >> Ausserdem pflegen Compiler auch morgen noch den gleichen Code zu >> erzeugen wie heute, wenn man weder das eigene Programm noch den Compiler >> aktualisiert. > > Da gibt's grad einen Thread im Forum, der sich damit beschäftigt, daß > das nicht stimmt. Interessanterweise gibt es offenbar gerade im > Optimizer von gcc sogar einen Teil, der für die Optimierung einen > Zufallsgenerator verwendet. Also bei FPGA's ist das zuweilen üblich, anderer Lauf, anderes Ergebnis. Ursache dafür ist das bei dem routing der Logicelemente Probleme (floorplanning) ähnlich des Traveling salesman zu lösen ist. Dafür nimmt man Lösungsverfahren wie simulated anealing. Und simulated annealing fängt in der ersten Iteration mit einer ausgewürfelten Lösung an. http://de.wikipedia.org/wiki/Simulated_annealing MfG,
A. K. schrieb: > Ausserdem pflegen Compiler auch morgen noch den gleichen Code zu > erzeugen wie heute, wenn man weder das eigene Programm noch den Compiler > aktualisiert. Wenn das so einfach ist, dann frag ich mich, was die Leute bei Debian (und auch wir, in der Firma) fuer Probleme beim Thema: "Rebuild Sicherheit" haben. Ist ja alles ganz einfach, wenn es nach dir geht. http://www.golem.de/news/softwaresicherheit-vertrauen-durch-reproduzierbare-build-prozesse-1502-112092.html Da scheint naemlich ne ganze Menge mehr rein zu spielen, als nur der zu ubersetzende Code und die Compilerversion. Aber bestimmt sind die Leute bei Debian einfach nur zu dumm... Just my 2 cent...
Rolf Magnus schrieb: > Da gibt's grad einen Thread im Forum, der sich damit beschäftigt, daß > das nicht stimmt. Interessanterweise gibt es offenbar gerade im > Optimizer von gcc sogar einen Teil, der für die Optimierung einen > Zufallsgenerator verwendet. Yep. Aber der Einfluss auf das Adresslayout des direkt erzeugten Codes dürfte gering bis nicht nicht existent sein. Einflüsse der Reihenfolge vom Linker sind ruppiger. Das muss man selber durch explizite Reihenfolge ausschliessen. Sonst ist man ohnehin geliefert. Im Steuerungsbereich bin ich zudem ein grosser Fan deterministischer Compiler. Es stört mich kein Bisschen, wenn SPECmark-Fans davon profitieren, aber embedded sollten Compiler m.E. konservativer arbeiten. Wenn ein Compiler mit nichtdeterministischer Codeerzeugung tatsächlich ein Zertifikat für kritische Embedded-Entwicklung kriegen kann, dann würde ich den Sinn solcher Zertifikate im Ersatz von Klopapier sehen.
Kaj G. schrieb: > Aber bestimmt sind die Leute bei Debian einfach nur zu dumm... Andere Umgebung, anderes Entwicklungsziel. Ich beziehe mich hier auf Entwicklung im Embedded Umfeld, verschärft noch durch Kuechles Adressvergabeproblem. Das ist schon ein wenig anders als die üblichen Debian-Builds. Hoffe ich jedenfalls. Wenn sich aber herausstellen sollte, dass beim nächste Airbus Debian am Steuer sitzt, dann ist's aus mit der Lust am Fliegen.
Fpga Kuechle schrieb: > Dann verste ich das Optimierungskonzept anders, also wenn Optimierung > aus -O0 wird dennoch loop-unrolling betrieben? Nein, Loop-Unrolling ist defaultmäßig nur bei -O3 aktiviert. -Os liefert aber unabhängig davon meist kürzeren Code als -O0, weil ja auch noch andere Dinge optimiert werden. > Bei Sizeoptimierung bleibt es im wesentlichen bei dem selben Problem: > Eigenschaften die aus dem Quelltext gezogen werden wie Größe > Daten/Codesegment stimmen nicht mit dem Kompilat überein, beispielsweise > Strings zusammenfassen. > const char[] str_message_ok "KEIN FEHLER"; > const char[] str_message_nok "EIN FEHLER"; Zumindest der GCC fasst gleiche Strings-Literale auch schon bei -O0 zusammen¹. Diesbezüglich wäre ein Verbot der Optimierung also nutzlos. Generell wird auch bei -O0 mehr optimiert, als man vielleicht erwarten würde. So werden bspw. konstante Teilausdrücke ausgewertet. Weil der Compiler dies in einigen Situationen sowieso tun muss, tut er es an allen anderen Stellen eben auch. Ebenso werden bei -O0 teilweise arithmetische Ausdrücke umgestellt, wenn ein dadurch entstehender Vorteil durch den Compiler ohne viel Aufwand erkennbar ist. Manchmal hilft das Einschalten der Optimierung sogar beim Aufdecken von Programmfehlern, bspw. von uninitialisierten Variablen. Um diese zu finden, muss der Compiler eine Datenflussanalyse machen, was er aber nur im Rahmen der Optimierung tut. Ich kann deswegen trotz deiner gut gemeinten Begründungsversuche wirklich nicht erkennen, was an nichtoptimierten Code besser sein soll als an optimierten, solange letzterer nicht auf Grund von Bugs im Optimierer fehlerhaft ist. Was in den jeweiligen Optimierungsstufen (einschließlich ausgeschalteter Optimierungsstufen) tatsächlich optimiert wird, hängt sehr stark vom verwendeten Compiler ab. Deswegen sollten vielleicht diejenigen, die die Optimierung verteufeln (wer auch immer die sein mögen), dies nicht pauschal tun, sondern genau spezifizieren, welche Arten der Optimierung aus welchen Gründen ihrer Meinung nach böse sind. ————————— ¹) ... wenn auch nicht in deinem Beispiel, weil dort die String nicht exakt gleich sind und zudem zwei unterschiedliche Variablen damit belegt werden.
Nase schrieb: > Deine Argumentation könnte man ja genauso auch so lesen: Der Optimierer > verringert das erzeugte Codevolumen (erheblich). Also wird auch weniger > Code ausgeführt, der Fehler haben könnte... Dass man die Fehlerwahrschienlichkeit durch bloße Verringerung der Anzahl der Maschinen-Instruktionen nicht drücken kann, sollte ja wohl klar sein. Es geht hier darum, ganze Module eines Programms komplett nicht zu nutzen. Das ist dann doch nochmal was anderes. Nase schrieb: > Rolf Magnus schrieb: >> Dein Verwendungszweck ist eben ein anderer. Wie würdest du das denn >> sehen, wenn du den Code für dein ESP damit übersetzen müßtest? Lieber >> besser optimieren, damit der Prozessor vielleicht eine nummer kleiner >> ausfallen kann, oder lieber sicherer? > Auch das basiert wieder auf der fragwürdigen Annahme, dass ein > Optimierer den Code potentiell fehlerträchtiger macht. Ich finde die nicht so fragwürdig. Ohne Optimierer werden einige Teile des Compilers, die besonders intensiv am generierten Code rumfuhrwerken, nicht genutzt. Dass sich das Potenzial für Fehler dadurch verringert, liegt meines Erachtens auf der Hand. > Wenn ich etwas für ein ESP übersetzen müsste, dann würde ich mir alle > greifbaren Compiler für die Zielarchitektur nehmen und den Quelltext in > allen Compilern mit allen Optimierungsstufen (oder sonstigen > Einstellungen derart) testen. Das kann man ja von mir aus während der Entwicklung machen - und danach den Optimizer ausschalten. Denn auch mit deiner Methode wird man nicht alle Fehler finden können. Und wenn nur ein Fehler drin ist (egal ob im Compiler oder im Code), der ohne Optimierung keine singifikante Auswirkung hat, dann hat sich's schon gelohnt. > Der Optimierer ist ja auch nur ein kleiner Teil. Würdest du deinen > Quelltext dann auch nicht modulweise übersetzen, sondern alles > zusammenkopieren? Linker und Präprozessor können auch Fehler machen. Die korrekte Funktion eines Linkers nachzuweisen, sollte aber deutlich leichter sein als die des Compilers.
Yalu X. schrieb: > Fpga Kuechle schrieb: >> Bei Sizeoptimierung bleibt es im wesentlichen bei dem selben Problem: >> Eigenschaften die aus dem Quelltext gezogen werden wie Größe >> Daten/Codesegment stimmen nicht mit dem Kompilat überein, beispielsweise >> Strings zusammenfassen. >> const char[] str_message_ok "KEIN FEHLER"; >> const char[] str_message_nok "EIN FEHLER"; > ————————— > ¹) ... wenn auch nicht in deinem Beispiel, weil dort die String nicht > exakt gleich sind und zudem zwei unterschiedliche Variablen damit > belegt werden. Ist dem so? Ich meine mal gelesen zu haben das manche compiler in diesem Fall nur einen String ablegen, und dann etweder auf das erste Zeichen 'K' für den längeren String und für den kürzeren auf 'E' als Stringanfang. Nannte sich string merging oder ähnlich. MfG,
Rolf Magnus schrieb: > Die korrekte Funktion eines Linkers nachzuweisen, sollte aber deutlich > leichter sein als die des Compilers. Seit Compiler einen Teil ihrer Arbeit dorthin verlagern, damit besser optimiert werden kann, nimmt die Komplixität von Linker recht heftig zu.
Fpga Kuechle schrieb: > Ist dem so? Ich meine mal gelesen zu haben das manche compiler in diesem > Fall nur einen String ablegen, und dann etweder auf das erste Zeichen > 'K' für den längeren String und für den kürzeren auf 'E' als > Stringanfang. Hast recht, es werden auch String-Literale, von denen das eine ein Suffix des anderen ist, optimiert. Das macht aber dann der Linker, und der auch nur mit eingeschalteter Optimierung. Beispiel:
1 | #include <stdio.h> |
2 | |
3 | const char *str_message_ok = "KEIN FEHLER"; |
4 | const char *str_message_nok = "EIN FEHLER"; |
5 | |
6 | int main(void) { |
7 | printf("%td\n", str_message_nok - str_message_ok); |
8 | return 0; |
9 | }
|
Ohne Optimierung -> 12 Mit Optimierung -> 1 Lässt man das 'K' im ersten String weg, gibt das Programm auch ohne Optimierung 0 aus, d.h. die beiden Pointer zeigen auf dasselbe Objekt.
:
Bearbeitet durch Moderator
Ich geh grad durch die Release Notes vom IAR für MSP430 durch: http://www.iarsys.co.jp/products/ew430-5401-infocenter/icc430.ENU.html Auszug: 1.11A 1997-09-11 C0007 Illegal optimization for assignments of type 'uint = uchar;' has now been removed. -- 1.22A 1999-11-25 C0013 Optimization level 3 now generates fully debuggable code. -> Interessant, funktioniert zwar auch mit Optimierung ist aber nicht mehr voll "debugbar" -- 1.25A 2001-11-09 C00020 The optimizer corrupted local pointers at higher optimizations than -s6, when decrementing more than twice. This has now been corrected. -- v 4.11B - 2008-07-10 In some cases, the assembler-level peephole optimizer could incorrectly rewrite code when mixing byte and word accesses to the same location in memory. -- Version 5.30.1 2011-06-30 EW22422: In special circumstance, an AND.W #1, Rx instruction is no longer incorrectly optimized away. Finde ich jetzt nicht besonders vertrauenserweckend, aber vielleicht ist der IAR eine schlechte Referenz. MfG
Rolf Magnus schrieb: > Du würdest also sagen, das das Steuersystem im A380 auch ruhig mit einem > Compiler übersetzt werden kann, der von irgendeiner Hinterhofklitsche > geschrieben wurde? Nein, da sollte man natürlich den breit getesteten und bewährten gcc nehmen und nicht den Compiler einer zertifizierten Hinterhofklitsche.
Fpga Kuechle schrieb: > Ich geh grad durch die Release Notes vom IAR für MSP430 durch: Lies dir mal die Errata eines aktuellen Intel-Prozessors durch und überlege, was man damit alles macht. Da wird dir vmtl. Angst und Bange und du wechselst stante pede auf RasPi (weil's dessen Errata nicht öffentlich gibt, also sind wohl auch keine drin ;-). Nützt nämlich nichts, wenn Programmierer und Compiler alles richtig machen, aber die Maschine Mist baut.
:
Bearbeitet durch User
A. K. schrieb: > Fpga Kuechle schrieb: >> Ich geh grad durch die Release Notes vom IAR für MSP430 durch: > > Lies dir mal die Errata eines aktuellen Intel-Prozessors durch und > überlege, was man damit alles macht. Ja hab ich gemacht und da steht: "Intel products are not intended for use in medical, life saving, life sustaining, critical control or safety systems, or in nuclear facility applications." http://www.intel.es/content/dam/www/public/us/en/documents/design-guides/celeron-400-guide.pdf Und da ich davon ausgehe, das bspw. die Medizintechnikfirmen nur dann certifiziert werden wenn sie solche produkte aussparen, kann ich völlig beruhigt das erata lesen und aus Fehlern anderer lernen. MfG,
Und du meinst, für jene Prozessoren und Systeme, denen du dich bedenkenlos anvertraust, existiert keine solche Liste?
Fpga Kuechle schrieb: > "Intel products are not intended for use in medical, life saving, life > sustaining, critical control or safety > systems, or in nuclear facility applications." Hm, also irgendwie schau ich da nicht völlig durch. Hier ein Medizintechnik-board mit intel: http://www.medizin-und-elektronik.de/elektronik-in-der-klinik/article/103617/0/Medical-Motherboards_mit_Core_i-Prozessoren/ Aber vielleicht ist ein CT mit diesem Board keine Medizintechnik im Sinne von "medical, life saving, life sustaining, critical control or safety systems, or in nuclear facility applications"???
NB: Solche Errata Sheets, oder etwas in der Art, gibts auch für Brücken und andere nicht gänzlich ungefährlichen Infrastrukturkomponenten. Und mit dem Alter werden die immer länger und länger. Aber das ist natürlich alles brav zertifiziert - d.h. jemand nickt es ab und alle hoffen, dass der olle Kram noch so lange hält bis wieder Geld in der Kasse oder jemand anderes dafür verantwortlich ist.
A. K. schrieb: > Und du meinst, für jene Prozessoren und Systeme, denen du dich > bedenkenlos anvertraust, existiert keine solche Liste? Und wo soll uns diese Diskussion über die Errate-liste hinführen? Ich halte nichts davon Compilerfehler unbeachtet zu lassen weil Hardware auch nicht perfekt ist. MfG, PS: http://www.baaske-medical.de/media/content/DerPC_keinMedizinprodukt.pdf klingt interessant - wird heute meine Bettlektüre.
Fpga Kuechle schrieb: > Fpga Kuechle schrieb: > >> "Intel products are not intended for use in medical, life saving, life >> sustaining, critical control or safety >> systems, or in nuclear facility applications." > > Hm, also irgendwie schau ich da nicht völlig durch. Hier ein > Medizintechnik-board mit intel: > > http://www.medizin-und-elektronik.de/elektronik-in-der-klinik/article/103617/0/Medical-Motherboards_mit_Core_i-Prozessoren/ Das ist nur für die Anwälte. Insbesondere in den USA, dem Land der unbegrenzten Schadensersatzklagen. Damit kann man sich prophylaktisch aus jeglicher Verantwortung stehlen und den schwarzen Peter elegant an das nächste Opfer (oder den nächsten Täter) in der Supply-Chain weiterreichen. Dumm dran ist nur derjenige der vergessen hat sowas ins Kleingedruckte seines Produktdatenblattes zu schreiben oder der gar keine Gelegenheit dazu hatte weil er zufällig der Endverbraucher ist.
:
Bearbeitet durch User
Yalu X. schrieb: > #include <stdio.h> > > const char *str_message_ok = "KEIN FEHLER"; > const char *str_message_nok = "EIN FEHLER"; > > int main(void) { > printf("%td\n", str_message_nok - str_message_ok); > return 0; > } Man sollte aber anmerken, dass dieser Code (abseits der Demonstration) fehlerhaft ist.
Fpga Kuechle schrieb: > Und da ich davon ausgehe, das bspw. die Medizintechnikfirmen nur dann > certifiziert werden wenn sie solche produkte aussparen, kann ich völlig > beruhigt das erata lesen und aus Fehlern anderer lernen. Ha-ha! Glaub das mal ruhig weiter... du würdest dich wundern, wo überall der Atom drinsteckt.
Nase schrieb: > Man sollte aber anmerken, dass dieser Code (abseits der Demonstration) > fehlerhaft ist. Ohne jetzt diesen Thread zu sehr ins Offtopic ziehen zu wollen: Verrätst du vielleicht kurz, wo der Fehler liegt? Ich kann ihn trotz mehrfachen Durchlesens nicht finden, lerne aber gerne noch etwas hinzu.
Yalu X. schrieb: > Ohne jetzt diesen Thread zu sehr ins Offtopic ziehen zu wollen: Verrätst > du vielleicht kurz, wo der Fehler liegt? Subtraktion von Pointern auf verschiedene Objekte. Du darfst nur Pointer auf das gleiche Objekt subtrahieren.
:
Bearbeitet durch User
A. K. schrieb: > Subtraktion von Pointern auf verschiedene Objekte. Ah ja, danke, jetzt hat's geschnackelt :) Dann macht also in diesem Fall das Einschalten der Optimierung aus fehlerhaftem Code korrekten Code, oder? ;-) Aber ich glaube, das ist eher eine philosophische Frage, für die wir, falls sie jemand diskutieren möchte, einen neuen Thread aufmachen sollten.
Vielen Dank für die interessante Diskussion. Beim Durcharbeiten von Literatur zur DO-254 (sichere komplexe Elektronik im Flieger) bin ich auf folgende Darstellung gestoßen, die m.E. die hier angerissenen Probleme von Optimierenden Compilern gut zusammanfasst. (aus 978-1-4822-0605-0) ... capability/complexity - Dichotomy : (Leistungsfähigkeit/Komplexitäts) -Zweiteilung leistungsfähigere (capability) tools sind mit einer höheren Komplexität (complexity) verbunden was wiederum zu einer Erhöhung der Unsicherheit (uncertainty) führt. Wesentliche Ziel bei der Entwicklung von sicherer designs ist die Verringerung der Unsicherheit bis zu beherrschbaren Maß ("to reduce uncertainty to managable levels") Deshalb muss mit jeder baugruppe, tool, design-feature oder design methode die das Potential für Unsicherheit erhöht in abwägender und überlegter Weise umgegangen werden ("needs to be dealt with in a deliberate manner") Dazu passen folgende Roys Regeln die an anderer Stelle als Kleines 1x1 des sicheren Entwurfes gelistet werden: -> "Make your design bulletproof even if no one is shooting at it" -> "Do not ask for trouble (Avoidance is better than mitigation)" -> "There is no hope ("We should never hope that our designs are safe, we should only know it for fact" Mein Fazit aus dieser Betrachtung ist: Optimierungen erhöhen die Wahrscheinlichkeit für Fehler (oder "Fehl-Optimierungen") bei der Code-Übersetzung. dem muß man angepasst entgegen wirken. Die radikalste Variante ist der Verzicht/Verhinderung von Automatischer Optimierung. MfG,
Stefan Us schrieb: > Äh ja, das wurde schon geschrieben. Ja aber IMHO nicht so stringent als: Wesentliche Ziel bei der Entwicklung von sicherer Designs ist die Verringerung der Unsicherheit bis zu beherrschbaren Maß ("to reduce uncertainty to managable levels") Und nicht mit belastbarer Quellenangabe mit Bezug auf einen etablierten Standard. MfG,
Yalu X. schrieb: > A. K. schrieb: >> Subtraktion von Pointern auf verschiedene Objekte. > > Ah ja, danke, jetzt hat's geschnackelt :) > > Dann macht also in diesem Fall das Einschalten der Optimierung aus > fehlerhaftem Code korrekten Code, oder? ;-) Der Code hat Undefined Behaviour, egal was der Compiler draus macht oder was du als Ergebnis erwartest.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.