Forum: Compiler & IDEs GCC: Arg unzulängliche Optimierungen?


von kxr (Gast)


Lesenswert?

mal wieder ein Beispiel - da derartiges oft vorkommt:

...
uint32_t result = 0;
uint8_t result8 = 0;

int main(void) {
  result = (uint32_t)a * b;
  result8 = result >> 18;
  return 0;
}


wird in -Os  -O2  -O3 so übersetzt :

  ldi r18,18   ; ,
1:  lsr r25   ;  D.1928
  ror r24   ;  D.1928
  ror r23   ;  D.1928
  ror r22   ;  D.1928
  dec r18   ;
  brne 1b
  sts result8,r22   ;  result8, D.1928


bei ">> 16" macht er halbwegs korrekt einen einfachen "movw r22,r24" 
(obwohl der auch überflüssig ist).

Es sollte doch naheliegend bei uint32_t >> 18 ein(kein) movw + 2 x 16bit 
ror/lsr gemacht werden - einfach so:

  lsr r25
  ror r24
  lsr r25
  ror r24
  sts result8,r24

ist das zuviel verlangt? das ist doch recht schlimm.
gibts AVR-Compiler die da deutlich besser sind?
nur mal wieder ein Beispiel für die die vielen arg unzulänglichen 
Optimierungen. da braucht man doch eigentlich kein fortgeschrittene KI?


jetzt greif ich so unter die Arme:

int main(void) {
  result = (uint32_t)a * b;
  result8 = (uint16_t)(result >> 16) / 4;
  return 0;
}

-- -O3 -------

  movw r22,r24   ;  tmp50, D.1928
  clr r24   ;  tmp50
  clr r25   ;  tmp50
  lsr r23   ;  tmp51
  ror r22   ;  tmp51
  lsr r23   ;  tmp51
  ror r22   ;  tmp51
  sts result8,r22   ;  result8, tmp51
.LM7:
  ldi r24,lo8(0)   ;  <result>,
  ldi r25,hi8(0)   ;  <result>,



=> na ja. aber warum löscht er stur r24,r25? und dann merkt er beim 
return nicht mal das schon 0en drin sind ;-) ...

liegt das allgemein am GCC oder am AVR-Teil?

von (prx) A. K. (prx)


Lesenswert?

Die 32-Bit Shift-Operationen sind für AVRs nicht optimal implementiert. 
Das ist bekannt und betrauert, aber bislang fand sich unter den 
Trauergästen keiner, der es dann auch verbessern wollte.

GCC geht eher davon aus, dass Shift-Operationen billig sind. Das hat 
manchmal negative Seiteneffekte in Form vom Fehloptimierungen, denn das 
sind sie bei AVRs meistens nicht. Schrumpfmaschinchen wie AVRs sind kein 
Hauptziel der GCC Entwicklung, da stehen eher dickere Boliden wie 
x86/amd64 und ARM im Vordergrund.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

kxr schrieb:

> ist das zuviel verlangt? das ist doch recht schlimm.
> nur mal wieder ein Beispiel für die die vielen arg unzulänglichen
> Optimierungen. da braucht man doch eigentlich kein fortgeschrittene KI?

avr-gcc ist ein Open-Source Compiler, du kannst mithelfen ihn zu 
verbessern.

Wenn solche Änderungen trivial für sich sind, mach eben ein Patch, 
spiels ein und die Sache ist aus der Welt.

Kein Grund, um zu weinen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Eine kurze Überschlagsrechnung für 32-Bit Shifts:

· Es gibt 3 mögliche Shifts (LSL, LSR, ASR)
· Es gibt 32 gültige Shift-Offsets (0..31)
· Es gibt Derivate mit MOVW und ohne
· Es gibt 4 Möglichkeiten, wie sich Quelle und Ziel überlappen können
· Es gibt mindestens 2 Optimierungs-Szenarien: Speed oder Codegröße

Macht 1536 = 3·32·2·4·2 Möglichkeiten.

Dabei sind noch nicht einmal Rotate oder variable Offsets 
berücksichtigt.

Zu den Implementierungen gehören dann auch noch die 
Kostenbeschreibungen.

Also, los geht's mit deiner KI!

Zudem gibt's noch mehr Unterscheidungskriterien:
· Wird eine Schleife ausgegeben und wird das Loop-Register danach
  weiter verwendet oder nicht?
· Ist nach der Registerklasse zu unterscheiden?
· Soll der Shift auf Memory passieren oder in Registern?

von Oliver (Gast)


Lesenswert?

Johann L. schrieb:
> Es gibt mindestens 2 Optimierungs-Szenarien: Speed oder Codegröße
> Macht 1536 = 3·32·2·4·2 Möglichkeiten.

Zur Vereinfachung könnte man ja zunächst mal ansetzen, daß der kürzeste 
Code auf einem AVR in der Regel auch der schnellste ist, RISC sei Dank.

Das reduziert die Varianten schon mal auf die Hälfte.

Oliver

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Oliver schrieb:
> Zur Vereinfachung könnte man ja zunächst mal ansetzen, daß der kürzeste
> Code auf einem AVR in der Regel auch der schnellste ist, RISC sei Dank.

No. Ein Librarycall für eine Division kostst:
2 Instruktionen zum Laden des Divisors
1 Instruktion für den Call

Am besten für -Os ist also eine Division :-)

von Oliver (Gast)


Lesenswert?

Johann L. schrieb:
> Am besten für -Os ist also eine Division :-)

Wenn die lib eh schon mit drin ist, ja ;)

Oliver

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Weiß man an der Stelle aber nicht. Und in ähnlich gelagerten Fällen auch 
nicht. Bzw. die Lib ist eh drinne, aber über die Funktion weiß man eben 
nix.

Zudem ist eine Schleife mitunter kürzer aber langsamer.

von Wanzer (Gast)


Lesenswert?

Qualifizierte Bugreports sind der erste Schritt. Ansonsten gibt es ja 
auch Compiler von Atmel.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wanzer schrieb:
> Ansonsten gibt es ja
> auch Compiler von Atmel.

So?  Welchen denn?

Atmel baut ICs, Compiler bauen andere. ;-)  Es gäbe den IAR, aber
das ist sowas wie der Mercedes unter den Compilern, da sind alle
Knöpfe dran vergoldet odre so.

von kxr (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Atmel baut ICs, Compiler bauen andere. ;-)  Es gäbe den IAR, aber
> das ist sowas wie der Mercedes unter den Compilern, da sind alle
> Knöpfe dran vergoldet odre so.

Hat jemand konkrete Erfahrungen wie der IAR bzgl. der hier diskutierten 
und ähnlichen, sonstigen.. Sachen besser optimiert als der AVR GCC?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

...und wer das Übel an der Wurzel packen und aus der Welt schaffen 
mochte und diesen für einige Anwender unerträglichen Übelstand beheben 
anstatt nur rumzumotzen ;-)

Die Funktion horcht auf den Namen lshrsi3_out und findet sich in
http://gcc.gnu.org/viewcvs/trunk/gcc/config/avr/avr.c?content-type=text%2Fplain&view=co

happy hacking

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

kxr schrieb:
> Hat jemand konkrete Erfahrungen wie der IAR bzgl. der hier diskutierten
> und ähnlichen, sonstigen.. Sachen besser optimiert als der AVR GCC?

Du kannst, je nach Programm, mit einigen Prozent bis vielleich maximal
so 20 % Codeeinsparung rechnen.  Als Nachteil schlagen zu Buche, dass
du das Ganze nur noch auf einem Computer benutzen kannst, vor dem du
auch physisch davor sitzen musst (kein Terminalserver, keine virtuelle
Maschine ­— zumindest ist das der Stand, den ich noch davon kenne),
dass du einige Tausender dafür hinblättern musst, dass du mit jeder
neuen Version worst case wieder einige Stunden verbringen kannst, bis
der ganze Lizenz-Mift wieder in Sack und Tüten ist, und natürlich, dass
es ihn ausschließlich für ein Betriebssystem gibt.

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
Noch kein Account? Hier anmelden.