- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 17

Thema: Softwaretest mit Code Optimierung

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076

    Softwaretest mit Code Optimierung

    Anzeige

    Powerstation Test
    Einen schönen guten Morgen,

    mich beschäftigt grade eine Frage wegen SOftwaretests.

    Ich habe eine C Software für ein Gerät "fertig ???" geschrieben.
    Nach ausgiebigen Tests "scheint" diese korrekt zu funktionieren.

    Wenn ich nun selbige Software mit der Compiler Option O1 O2 (sprich Optimierungen) compiliere
    funktioiert so gut wie garnichts mehr.

    Jetzt die Frage:

    Muss eine C Software mit sämtlichen Compileroptionen getestet und lauffähig gemacht werden ?

    PS:
    Warum da einiges nicht mehr funktioniert hat verschiedene Ursachen, die ich schon teiweise ermitteln konnte.

    Prozessorspezifische Interrupt Eigenschaften, plötzlich "volatile" erforderlich, Code wegoptimiert.....

    Ich bekomme sie sicherlich auch in jeder Optimierung zum Laufen, darum geht es nicht.

    Ist das erforderlich ist meine Frage. Zudem könnte ich mir vorstellen, dass ein Compiler von beispielsweise IAR
    eine anderen Assemblercode erzeugt als ein GNU Compiler, bei Optimierungen ebenfalls Unterschiede entstehen.

    Danke Euch für Informationen.

    Siro

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    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

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    66
    Beiträge
    2.435
    Hallo Siro,
    Zitat Zitat von Siro Beitrag anzeigen
    Muss eine C Software mit sämtlichen Compileroptionen getestet und lauffähig gemacht werden ?

    PS:
    Warum da einiges nicht mehr funktioniert hat verschiedene Ursachen, die ich schon teiweise ermitteln konnte.

    Prozessorspezifische Interrupt Eigenschaften, plötzlich "volatile" erforderlich, Code wegoptimiert.....

    Ich bekomme sie sicherlich auch in jeder Optimierung zum Laufen, darum geht es nicht.

    Ist das erforderlich ist meine Frage. Zudem könnte ich mir vorstellen, dass ein Compiler von beispielsweise IAR
    eine anderen Assemblercode erzeugt als ein GNU Compiler, bei Optimierungen ebenfalls Unterschiede entstehen.
    Im wesentlichen gibt es zwei, sich widersprechende, Optimierungen:
    - Codegrösse
    - Geschwindigkeit

    Von daher müssen nie beide Optimierungen sein
    Grundsätzlich muss nicht optimiert werden, Codegrösse kann helfen, ein grosses Programm noch ins ROM zu bringen.

    Grundsätzlich sollte der Code nicht kaputt optimiert werden, zumindest von der Ablauflogik her.
    Das andere Problem ist das Laufzeitverhalten, hier ändert sich das Timing, was zu Problemen mit der Peripherie führen kann.

    Von der Programmlogik kann eine leere for-Schlaufe wegoptimiert werden, da deren Entfernen nichts an der Ablauflogik ändert. Dumm nur wenn das ein Delay war

    Allerdings kann man die Optimierung auch meistens über #pragma im Code steuern, sodass man kritische Teile von der Optimierung ausnehmen kann.

    Das mit dem "volatile"-Problem verstehe ich nicht so ganz? Da vermute ich, dass da grundsätzlich etwas nicht ganz sauber im Programm ist, aber erst beim Optimieren wirklich entdeckt wird.
    Typisches Beispiel:
    Code:
    while (!Status)
      {
        // warten bis bereit
      }
    Ohne Optimierung wird Status bei jedem Durchgang neu geladen.
    Bei der Optimierung auf Geschwindigkeit wird "Status" nur einmal geladen und in einem Register aufbewahrt, das spart Speicher-, bzw. Peripherie-Zugriffe.
    Nun ist es aber so, dass man bei einer sauberen Programmierung z.B. I/Os IMMER als "volatile" deklariert!
    "volatile" ist besonders wichtig bei der Optimierung und besagt dem Compiler, dass sich der Zustand dieser Variablen jederzeit ändern kann, auch wenn dies vom Programmablauf her nicht "sichtbar" ist.
    Ein C-Compiler kennt den Unterschied zwischen einer normalen Variablen im RAM und einem Port nicht. Allerdings kann "volatile" auch wichtig sein, wenn eine Variable in einer ISR verändert wird.

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

  4. #4
    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.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    66
    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?

  6. #6
    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.

  7. #7
    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)

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

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    66
    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?

  10. #10
    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

Seite 1 von 2 12 LetzteLetzte

Ä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
  •  

Solar Speicher und Akkus Tests