gcc 4.0.0 erzeugt schlechteren Code

Gast #181441
Lesenswert?

Hallo!

Ich hab einen Codevergleich zw. gcc 3.4.1 und 4.0.0 gemacht.
Hier zuerst der Code aus 3.4.1:
void
wait (uint16_t zeit)
{
      f6:       9c 01           movw    r18, r24
      f8:       01 c0           rjmp    .+2             ; 0xfc
        while (zeit > timer2)
                asm volatile ("nop");
      fa:       00 00           nop
      fc:       80 91 75 01     lds     r24, 0x0175
     100:       90 91 76 01     lds     r25, 0x0176
     104:       82 17           cp      r24, r18
     106:       93 07           cpc     r25, r19
     108:       c0 f3           brcs    .-16            ; 0xfa
     10a:       08 95           ret

0000010c <init_timers_z>:
}

Hier mit 4.0.0:

void
wait (uint16_t zeit)
{
      f4:  9c 01         movw  r18, r24
  while (zeit > timer2)
      f6:  80 91 7b 01   lds  r24, 0x017B
      fa:  90 91 7c 01   lds  r25, 0x017C
      fe:  82 17         cp  r24, r18
     100:  93 07         cpc  r25, r19
     102:  40 f4         brcc  .+16       ; 0x114
    asm volatile ("nop");
     104:  00 00         nop
     106:  80 91 7b 01   lds  r24, 0x017B
     10a:  90 91 7c 01   lds  r25, 0x017C
     10e:  82 17         cp  r24, r18
     110:  93 07         cpc  r25, r19
     112:  c0 f3         brcs  .-16       ; 0x104
     114:  08 95         ret

00000116 <init_timers_z>:
}
Gast #181443
Lesenswert?

Noch ein Nachtrag:
Wenn ich das NOP rausnehme (timer 2 ist volatile uint16_t) siehts
wieder besser aus mit 4.0.0:

void
wait (uint16_t zeit)
{
      f4:  9c 01         movw  r18, r24
  while (zeit > timer2);
      f6:  80 91 7b 01   lds  r24, 0x017B
      fa:  90 91 7c 01   lds  r25, 0x017C
      fe:  82 17         cp  r24, r18
     100:  93 07         cpc  r25, r19
     102:  c8 f3         brcs  .-14       ; 0xf6
     104:  08 95         ret

00000106 <init_timers_z>:
    // asm volatile ("nop");
}
Gast #181447
Lesenswert?

void
wait (uint16_t zeit)
{
      f4:  9c 01         movw  r18, r24
      f6:  01 c0         rjmp  .+2        ; 0xfa
  while (zeit > timer2)
   asm volatile ("nop");
      f8:  00 00         nop
      fa:  80 91 4a 02   lds  r24, 0x024A
      fe:  90 91 4b 02   lds  r25, 0x024B
     102:  82 17         cp  r24, r18
     104:  93 07         cpc  r25, r19
     106:  c0 f3         brcs  .-16       ; 0xf8
     108:  08 95         ret

0000010a <init_timers_z>:
}

Ok. Mit -Os passts wieder. Allerdings brauch ich -O2 wegen anderer
Optimierungen. Aber ich hab mal gezählt:
Wenn die Bedingung beim ersten mal nicht zutrifft, ist der 4.0 in 7
Takten durch, mit 3.4.1 mit 8 Takten.
Also ist der 4.0 code doch schneller wenn man nur nachzählt.

Sorry für den Wirbel...
Gast #181450
Lesenswert?

Benchmarks lügen doch eh immer!

Bei einigen Routinen bringt -O2 bei mir ca. 30% Laufzeitverbesserung
(z.B. Software-PWM für 24 Kanäle). Bei einigen kritischen Stellen schau
ich mir den Code auch an, und da sieht man deutlich den Unterschied.
Wobei ich jedoch meist zw. -O0 und -O2 vergleiche.
Die Sachen die ich grad schreib sind z.T. recht zeitkritisch. Und ich
will nicht schuld sein, wenn dauernd Schiffe kollidieren oder
ungebremst auf die Kaimauer zurasen :-)
Gast #181452
Lesenswert?

Hi

-O0 schaltet den optimierer komplett aus. Das sollte man nicht mit
eingeschalteter Optimierung (egal welcher) vergleichen. Wie Andreas
schon geschrieben hat: Vergleiche -Os mit -O2. Du wirst kaum einen
Unterschied erkennen können.

Matthias

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren