- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: Optimierungslevel & Funktionalität ?!

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    31.03.2007
    Ort
    Dortmund
    Alter
    39
    Beiträge
    31

    Optimierungslevel & Funktionalität ?!

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo Gemeinde!

    Seit einer Stunde wieder an meinem ATmega8 Motortreiber sitzend stelle ich gerade erstaunt fest, dass das "Optimization level" des AVR Studios die Funktionsweise meines Codes beeinflusst.
    Ich will ein PWM Signal auf 2 Ports ausgeben durch:

    Code:
      if(motortick < mot1)
       MOTOR1_PORT |= (1<<MOTOR1_PIN);
      else
       MOTOR1_PORT &= ~(1<<MOTOR1_PIN);
    
      if(motortick < mot2)
       MOTOR2_PORT |= (1<<MOTOR2_PIN);
      else
       MOTOR2_PORT &= ~(1<<MOTOR2_PIN);
    wobei motortick von einem Timer hochgezählt wird und mot1,2 die Intensität des Signals verändert.
    Kompiliere ich mit Optimierungsstufe s, 1, 2 oder 3, sind die Ausgänge immer auf high, mit 0 hingegen funktioniert es richtig prima (allerdings ist die HEX 4 mal so groß).

    Eigentlich dürfte doch eine Optimierung die Funktion des Skripts nicht verändern, oder?
    Gibt es vielleicht etwas zu berücksichtigen wenn man mit 's' programmiert?

    Gruß,
    Markus

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    19.03.2005
    Ort
    Villach
    Alter
    33
    Beiträge
    995
    Hallo Zarathustra!

    Gib uns doch mal deinen ganzen code.

    mein optimeren werden schleifen wie

    while (PORTB | (1<<PB5)); etc wegoptimiert. sie müssen
    while (PORTB | (1<<PB5)) {
    ; //Achtung: ein ; ist hier
    }
    angeschrieben werden.

    lg
    Thomas

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    while (PORTB | (1<<PB5)) {
    ; //Achtung: ein ; ist hier
    }
    angeschrieben werden.
    Klar optimiert er das weg (PORTB | (1<<PB5)) ist immer wahr...

    @Markus,
    hast Du motortick als volatile deklariert ?

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    31.03.2007
    Ort
    Dortmund
    Alter
    39
    Beiträge
    31
    Hallo Superhirn,

    Das gepostete war eigentlich schon fast der gesamte Code und das hochzählen durch den Timer2 Interrupt funktioniert problemlos auch unter "s".
    Zu deinem Code: ich würde izaseba zustimmen und besser PORTB & (1<<PB5) schreiben, weil 1 oder 0 immer eins ist.

    @izaseba,
    ich habe auf deinen Hinweis hin mal ganz unverbindlich ein volatile hingeschrieben (volatile unsigned int compfreq, motortick, mot1, mot2) und siehe da: es funktioniert
    Erstaunlich..
    Eine kurze Erklärung was genau das volatile dort anstellt?

    thx & Gruß,
    Markus

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    19.03.2005
    Ort
    Villach
    Alter
    33
    Beiträge
    995
    ja da hab ich mich vertan mit den & und |. sry.

    ohne volatile wird von der variable eine kopie im register angelegt damit sie schneller ist. und diese kopie kann jedoch nicht durch einem interrupt etc verändetr werden.
    das volatile verhindert das kopien angelegt werden.

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Eine kurze Erklärung was genau das volatile dort anstellt?
    Gerne, volatile bezeichnet die Variable als flüchtig, d.h. bei jedem Zugriff soll sie bitteschön aus dem Speicher gelesen oder geschrieben werden.
    Das hindert den Compiler daran sie in einem Register zu halten, weil der Inhalt an einer anderen Stelle (bei Dir der Timerinterrupt) geändert werden könnte, ohne das der Prozessor es merkt.
    Variablen, die für die Komunikation zwischen Interrupts und Hauptprogramm zuständig sind, sind daher als volatile zu deklarieren, es sei den man macht die Optimierung weg (-O0) was ja nicht gerade Sinn macht(wie Du leider feststellen musstest)

    Ich hoffe, daß es verständlich genug war

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    ja da hab ich mich vertan mit den & und |. sry.
    Solltest Du die UND Verknüpfung gemeint haben, bestehe ich darauf, daß ein
    Code:
    while (PORTB & (1<<PB5)); etc wegoptimiert. sie müssen
    nicht wegoptimiert wird, hier was GCC bei -Os daraus macht:
    Code:
      while (PORTB&(1<<PB5));
      fa:	c5 99       	sbic	0x18, 5	; 24
      fc:	fe cf       	rjmp	.-4      	; 0xfa <main+0x1c>
    Ich hoffe, daß Du soviel Assembler verstehen wirst.

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    19.03.2005
    Ort
    Villach
    Alter
    33
    Beiträge
    995
    ok ich verstehe es in asm so halbwegs.

    danke ich dachte immer das ist so.

    aber:
    Code:
        ...
        uint16_t i;
     
        /* leere Schleife - wird bei eingeschalteter Compiler-Optimierung   wegoptimiert */
        for (i = 0; i < 1000; i++)
          ;
     
        ...
     
        /* Schleife erzwingen (keine Optimierung): "NOP-Methode" */
        for (i = 0; i < 1000; i++)
          asm volatile("NOP");
     
        ...
     
        /* alternative Methode (keine Optimierung): */
        volatile uint16_t j;
        for (j = 0; j < 1000; j++)
          ;
    ist von mikrocontroller.net kopiert damit man wies wie die for nicht wegoptimiert wird :P

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    31.03.2007
    Ort
    Dortmund
    Alter
    39
    Beiträge
    31
    Gute Erklärungen,
    ich habe es verstanden und werde mich gleich daran begeben all meine "Interruptvariablen" als volatile zu erklären \/

    Danke nochmal,
    einen schönen Abend noch,
    Markus

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    23.06.2005
    Ort
    München
    Beiträge
    113
    while (PORTB | (1<<PB5)); etc wegoptimiert. sie müssen
    while (PORTB | (1<<PB5)) {
    ; //Achtung: ein ; ist hier
    }
    angeschrieben werden.
    @Superhirn:
    IMHO sind obige Zeilen C absolut identisch und werden nicht
    unterschiedlich optimiert. Sprich: der erzeugte Code ist absolut
    identisch. Dem compiler ist es egal ob der Block hinter dem
    while explizit oder implizit leer ist.

    Und wie bist du eigentlich auf dieses Beispiel gekommen, daß
    überhaupt nichts mit der Originalfrage zu tun hat.

    @Izaseba:
    Nachdem boolsche Ausdrücke von links nach rechts ausgewertet
    werden glaube ich das ein "while (var | 1)" niemals wegoptimiert wird
    (auch wenn das Ergebnis immer bekannt ist).

    @Zarathustra:
    Solange du nur motortick in deinem Interrupt verändernst (und nicht
    mot1 oder mot2) reicht es auch nur motortick als volatile zu deklarieren.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

12V Akku bauen