- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 17

Thema: Softwaretest mit Code Optimierung

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.698
    Hallo Siro,

    meine eigenen Erfahrungen (und mein Wissen) dazu sind bescheiden. ABER - meine aktuelle Platinenbestückung für meinen Archie ist doch recht komplex, zwölf mit UART oder I²C-verbundene Platinen, davon sechs mit z.T. ziemlich interruptdurchseuchtem Code.
    Zitat Zitat von Siro Beitrag anzeigen
    .. Wenn ich nun selbige Software mit der Compiler Option O1 O2 (sprich Optimierungen) compiliere
    funktioiert so gut wie garnichts mehr ..
    Muss eine C Software mit sämtlichen Compileroptionen getestet und lauffähig gemacht werden ? ..
    Programmier-IDE ist bei mir Studio 4, optimiert wird immer mit -Os. Das hat natürlich auch die Notwendigkeit dass ich so ziemlich alle irgendwie "verdächtige" Variablen als volatile deklariere, wenns sinnvoll erscheint dann wird das natürlich auch mit Startwerten definiert. Gerade "Startwerte" sind so ne Sache. Die NOtwendigkeit wird nicht IMMER geprüft - oft nur aus der Erfahrung vermutet. Da könnten ja zur Laufzeit Variablenwerte (die nicht-atomaren) in Interruptserviceroutinen verändert werden - während sie in der gerade unterbrochenen Routine bearbeitet werden. Und das kann der Compiler so optimieren, dass Du Trouble bekommst. Auch ohne Optimierung sind gerade nicht-atomare Operationen sehr empfindlich auf Interrupts.

    Eine gewisse Überprüfung - allereinfachster Art - wäre natürlich die Angabe des Compilers über den verbrauchten Speicherplatz als Flash und SRAM (also Program und Data) bei verschiedenen Optimierungen zu vergleichen. Steht die Optimierung überhaupt dafür - im Sinne eines sparsameren Codes? BRAUCHST Du sparsameren Code? Andererseits - sehr geschachtelte Routinen und/oder reichlich ISR brauchen jede Menge Stack. Da gibts empfehlungen die oberen 20 oder mehr Prozent SRAM frei zu halten - ich habe auch schon Empfehlungen von bis zu 50 Prozent gelesen.

    (M)EIN knappes, einfachs Fazit also: "verdächtige" oder eben mehrfach benutzte Variablen als volatile deklarieren erspart manchen Kummer.
    Ciao sagt der JoeamBerg

  2. #2
    shedepe
    Gast
    Man könnte auch behaupten, wenn man nach der Spezifikation programmiert klappt das.

    Es ist nunmal so, dass unterschiedliche Compiler sich unterschiedlich verhalten. So lange man sich aber innerhalb der Spezifikationen der Programmiersprache - bzw. der Ergänzungen der Compiler aufhält, sollte man nicht befürchten, dass es Probleme hinsichtlich des entstehenden Binärcodes gibt.

    Man muss sich eben davor einlesen, was die Toolchain bzw. die Sprachspezifikation z.B. zu Codeoptimierung sagt. Bzw. die Prinzipien dahinter verstehen.

    Du forderst von deinem Compiler dass er Code Optimiert. Je nach Einstellung macht er das anders. Das musst du dir davor anschauen.
    Die meisten Optimieren haben aber gemeinsam: Zuerst schaut der Compiler: gibt es unnötigen Code. Also Code der nicht aufgerufen wird. Wenn ja (das trifft für Interruptroutinen zu bzw. Variablen die dort verwendet werden). Aus Sicht des Compilers wird die Interruptroutine nie aufgerufen ( denn deine Hardware macht das). Also kann er gefahrlos die Variablen wegoptimieren (sie werden ja nicht benötigt) . Volatile gibt an: Nein die Variable wird gebraucht auch wenn du das nicht siehst.

    Achtung außerdem. Volatile auf dem PC bedeutet etwas ganz anderes.

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Hallo,
    Zitat Zitat von oberallgeier Beitrag anzeigen
    Eine gewisse Überprüfung - allereinfachster Art - wäre natürlich die Angabe des Compilers über den verbrauchten Speicherplatz als Flash und SRAM (also Program und Data) bei verschiedenen Optimierungen zu vergleichen.
    Moderne C-Compiler unterscheiden sich heute meistens nur noch bei der Optimierung, den Speichermodellen und den mitgelieferten Zusatz-Bibliotheken. Die Standard-Bibliotheken sind durch ANSI-C vorgegeben.

    Zitat Zitat von oberallgeier Beitrag anzeigen
    Andererseits - sehr geschachtelte Routinen und/oder reichlich ISR brauchen jede Menge Stack. Da gibts empfehlungen die oberen 20 oder mehr Prozent SRAM frei zu halten - ich habe auch schon Empfehlungen von bis zu 50 Prozent gelesen.
    Allgemeine Empfehlungen sind Quatsch!
    Wie du richtig erkannt hast, spielt die Verschachtelung eine grosse Rolle. Zum Stackbedarf des Hauptprogrammes, muss jederzeit auch noch genügend Platz für, allenfalls auch geschachtelte, Interrupts frei bleiben. Neben dem Hardwarebedingten Platz für die Rücksprungadresse und zu rettende Register, kommen aber auch noch die Auto-Variablen hinzu!
    Hier macht dann die Anwendung und das können des Programmierers den Stackbedarf aus.

    Zitat Zitat von oberallgeier Beitrag anzeigen
    (M)EIN knappes, einfachs Fazit also: "verdächtige" oder eben mehrfach benutzte Variablen als volatile deklarieren erspart manchen Kummer.
    Eigentlich sollte man da nicht mit raten dran gehen, sondern mit Wissen

    Jede Variable, welche sich ausserhalb des gerade sichtbaren Codes ändern kann, MUSS als "volatile" deklariert werden!
    Also Variablen, welche in Interrupts verändert werden und natürlich fast alles was zur Peripherie gehört. Logischerweise die Ports und Timer, aber auch Register welche Status-Bits enthalten.

    MfG Peter(TOO)

    P.S. Ich habe ganz früher einige einfache Compiler selbst entwickelt, einer war für die Verarbeitung von Verdrahtungslisten für eine Simulation. Eine Art Hochsprache kann man auch mit einem guten Macro-Assembler erstellen. Ende 80er habe für den 6301, ein 6801 Derivat, habe ich einen Optimizer geschrieben, welcher den Assembler-Code optimiert hat. Der Compiler machte viel zu viel unnötige Registertauschereien. Im Prinzip hatte dieser Compiler Übergabekonventionen zwischen den Code-Zeilen, so in der Art wie man das auch bei einem Funktionsaufruf hat, vereinfacht natürlich den Compiler.
    Von etwa 1990 bis 2000 habe ich am IAR-Compiler für die Hitachi-H8 Familie mitgewirkt.
    Geändert von Peter(TOO) (27.10.2015 um 10:53 Uhr)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Ersteinmal vielen Dank für Eure Informationen.

    Vorab: Ich muss glücklicherwiese nichts optimieren, weder aus Speichertechnischen noch aus Geschwindigkeitsgründen.

    Durch verschiedene Optionen möchte ich jedoch im Vorfeld schon "kritischen Code" erkennen, um eine möglichst "saubere"
    Software zu generieren.

    Das "volatile" ist natürlich zwingend erforderlich zum Beispiel bei meiner "SystemTickcount" Variablen.

    Meine Dummy Variable zum Lesen eines Registers um lediglich ein Interrupt Bit zu löschen muss dann auch "volatile" sein,
    sonst optimiert mir der Compiler die Zeile gänzlich weg, frei nach dem Motto: Was Du nicht benutzt, brauchst Du auch nicht

    Kritisch ist generell das Löschen von Interrupbits beim Cortex-M3. Das sollte man tunlichst nicht in der letzten Zeile tun.
    Das geht dann plötzlich nicht mehr und es wird ein Dauer oder doppelter Interrupt ausgelöst.

    Zur Zeit hängt die Software jedoch immer noch fest und ich bin noch auf der Suche.

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Ich möchte das Thema nochmal aufgreifen, da ich neue "merkwürdige" Erkenntnisse gewonnen habe:

    Mein Code läuft jetzt mit Allen möglichen Optimierungen, das war ein gutes Stück Arbeit.
    Ein Fehler hat wirklich lange gedauert und dieser ist mir auch bisher nicht erklärlich. Vielleicht habt Ihr eine Erklärung dafür:

    Diese Zeile hat der Compiler wegoptimiert wenn *base nicht volatile ist */
    das darf er doch nur, wenn er wüste, dass da schon 0x83 drin steht, dem ist aber nicht so
    *(base + UART_LCR) = 0x83; /* DLAB = 1 , 8 bits, no Parity, 1 Stop bit */

    Dazu ein Ausschnitt aus dem Code zum Initialisieren der seriellen Schnittstelle:

    Code:
    /*----------------------------------------------------------------------------*/
    void uart_init(const U8 UartNo,const U32 baudrate)
    { volatile U8* base;
    
      base = (U8*) UART_BASE[UartNo];       /* base address of uart, Basisadreesen sind im Array abgelegt */
    
      *(base + UART_LCR) = 0x83;                /* <---- Zeilenklau Compiler      DLAB = 1 ,  8 bits, no Parity, 1 Stop bit */
      
      /* .............Werte für DLL und DLM setzen............. */
    
      *(base + UART_LCR) = 0x03;             /* <--- diese Zeile lasst der Compiler drin    DLAB = 0 ,  8 bits, no Parity, 1 Stop bit */
      
    }

    warum verschwindet die Zeile lediglich bei Optimierungsstufe -O3 ?

    Siro

    PS. Das ist LPCXpresso v7.9.2 [Build 493] [2015-09-14]
    Gnu-Compiler C/C++ GNU Toolchain Build Support 8.6.0.201502131403 org.eclipse.cdt.gnu.build.feature.group Eclipse CDT
    Geändert von Siro (03.12.2015 um 13:22 Uhr)

  6. #6
    shedepe
    Gast
    Sofern ich das auf die Schnelle sehe sind bereits alle Werte bekannt.

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Hallo Siro,

    Ist doch für einen Automaten logisch! :-=

    Code:
    a = 0x83;
    a = 0x03;
    Da steht am Schluss immer 0x03 in a!

    Wie schon geschrieben wurde, ist das ohne volatile für den Compiler nur eine Variable im Speicher!
    Code:
    a = 0;
    a = 1;
    a = 2;
    a = 3;
    Da macht nur a =3; Sinn, die anderen Werte werden dauernd überschrieben ohne je gelesen zu werden.

    Die CPU, und der Compiler, behandeln bei dieser Architektur Register und Speicher genau gleich, da gibt es keinen Unterschied.
    Da muss man dann halt mit volatile "nachhelfen" und den Compiler beibringen, dass sich diese Speicherzellen auch ohne zutun des Programms änder können, bzw. das Setzen und anschliessende Löschen eines Bits etwas bewirken.

    Es gibt Architekturen, bei denen I/Os am einem separaten Bus hängen, da kann das der Compiler dann an der Adresse unterscheiden. z.B. der 8080 und auch die Nachfolger 8086 bis Pentium haben so einen separaten I/O-Bus. Beim 8080 gab es 256 I/O-Adressen, beim 8086 waren es dann 65KByte. Natürlich kann man aber auch bei dieser Familie I/Os im normalen Speicherbereich einbinden.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Jetzt, wo Du es so erklärst, fällt auch bei mir der Groschen (Centweise )

    Na klar, der Compiler sieht, dass ich einer Variablen einen Wert zuweise, nix damit mache und dann einen neuen Wert zuweise.
    Er kann den Sinn natürlich nicht erkennen, dass ich dies tue um an spezielle Register im UART heranzukommen.

    Das leuchtet mir jetzt auch ein und damit hat er recht und darf das wegoptimieren.
    Vielen Dank Peter

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Hallo,
    Zitat Zitat von Siro Beitrag anzeigen
    Jetzt, wo Du es so erklärst, fällt auch bei mir der Groschen (Centweise )
    Dann bist du jetzt reich

    Es gibt noch weitere Optimierungen, das wird dann auch die Reihenfolge der Befehle umgestellt, z.B. um die FPU besser auszunutzen, kann man, während die FPU gerade rechnet noch ein paar Integer-Befehle abarbeiten. Das hängt dann aber sehr von der CPU-Architektur ab. Bei manchen RISC-CPUs geht das so weit, dass das Return einer Subroutine VOR dem letzten Befehl stehen muss!

    Grundsätzlich muss man bei Funktionen, welche direkt I/Os bedienen mit der Optimierung sehr genau aufpassen! :Strom
    Meistens ist es am Besten diese separat auszulagern und ohne Optimierung zu übersetzen.
    Andernfalls kann schon eine neue Version des Compilers, mit verbesserter Optimierung, zu einem anderen Timing, und folglich zu Fehlern, führen.

    Noch etwas grundsätzliches zur Funktion eines Compilers:
    Zuerst wird eine lexikalische Prüfung vorgenommen, dabei wird im Prinzip die Rechtschreibung überprüft.
    Anschliessend folgt die syntaktische Prüfung, bei welcher festgestellt wird ob aus den Wörtern auch gültige Sätze gebildet wurden.
    Anschliessend bildet man eine Baumstruktur, welche den logischen Programmablauf darstellt und eigentlich Sprachunabhängig ist.
    Diesen Sprachabhängigen Teil nennt man Front End.

    An diesem Baum erfolgt dann die erste Optimierung, wie z.B. das wegoptimieren von unnötigen Variablen-Zugriffen und totem Code.

    Der Code-Generator (Back End) erzeugt dann aus dem Baum den eigentlichen Maschinencode. Dieser Teil ist dann CPU spezifisch.
    Hier wird dann weiter optimiert, vor allem da hin gehend, dass man viel benutzte Variablen möglichst in einem Register behält und erst am Ende der Berechnung in den Speicher schreibt (volatile verhindert auch diese Optimierung).
    Weitere Optimierungen sind z.B. bei einer Multiplikation mit 2, das Ersetzen durch eine Addition oder einen Links-Shift, je nachdem was halt schneller ist.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

Ähnliche Themen

  1. PROGMEM und Optimierung
    Von Ceos im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 09.10.2013, 07:15
  2. BASCOM Code-Optimierung - Was tut sich genau?
    Von Thomas E. im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 03.02.2012, 19:17
  3. Code Optimierung für Interrupt möglich?
    Von erik_wolfram im Forum C - Programmierung (GCC u.a.)
    Antworten: 15
    Letzter Beitrag: 13.09.2011, 22:21
  4. [ERLEDIGT] Fehler im Code? Optimierung nicht optimal? überfordert!
    Von erik_wolfram im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 30.03.2011, 17:27
  5. Code Optimierung
    Von Siro im Forum C - Programmierung (GCC u.a.)
    Antworten: 10
    Letzter Beitrag: 19.08.2010, 22:45

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress