Forum: Compiler & IDEs Hardware-Multiplier auf Mega32 ungenutzt?


von Hundertvolt (Gast)


Lesenswert?

...jetzt wundert mich der GCC aber gewaltig.

Übersetzt der den Befehl:
1
Calc *= H_SENS_MUL;

(zur Info: Calc ist ein unsigned short int, H_SENS_MUL eine 
#define-Konstante mit in diesem Fall dem Wert 15)


...zu diesem hier:
1
    Calc *= H_SENS_MUL;
2
 642:  c9 01         movw  r24, r18
3
 644:  44 e0         ldi  r20, 0x04  ; 4
4
 646:  88 0f         add  r24, r24
5
 648:  99 1f         adc  r25, r25
6
 64a:  4a 95         dec  r20
7
 64c:  e1 f7         brne  .-8        ; 0x646 <H_Sens_Read+0x84>
8
 64e:  82 1b         sub  r24, r18
9
 650:  93 0b         sbc  r25, r19

Also wohl die Multiplikation durch eine Additionsschleife.

Warum setzt er nicht den Hardware-Multiplier vom ATMega32 mit dem 
MUL-Befehl ein? Das sollte doch mit 16bit-Variablen schrittweise, 
Register für Register genauso wie eine Addition möglich sein und 
deutlich weniger Zyklen brauchen!

Wie bring ich ihn dazu, den MUL zu nehmen?

von Karl H. (kbuchegg)


Lesenswert?

Hundertvolt schrieb:
>
1
>     Calc *= H_SENS_MUL;
2
>  642:  c9 01         movw  r24, r18
3
>  644:  44 e0         ldi  r20, 0x04  ; 4
4
>  646:  88 0f         add  r24, r24
5
>  648:  99 1f         adc  r25, r25
6
>  64a:  4a 95         dec  r20
7
>  64c:  e1 f7         brne  .-8        ; 0x646 <H_Sens_Read+0x84>
8
>  64e:  82 1b         sub  r24, r18
9
>  650:  93 0b         sbc  r25, r19
10
>
>
> Also wohl die Multiplikation durch eine Additionsschleife.

Schon.
Aber die Schleife wird nur 4 mal durchlaufen.

> Warum setzt er nicht den Hardware-Multiplier vom ATMega32 mit dem
> MUL-Befehl ein?

Wal das bei einer 16*16 Bit Multiplikation auch schon ziemlicher Aufwand 
mit Zwischenergebnissen und deren Addition bedeutet. Ganz zu schweigen 
davon, dass die entsprechenden Register auch freigeschaufelt werden 
müssen.

> Das sollte doch mit 16bit-Variablen schrittweise,
> Register für Register genauso wie eine Addition möglich sein und
> deutlich weniger Zyklen brauchen!

Ich denke, du kannst dich darauf verlassen, dass derjenige, der den 
Compiler konfiguriert hat, schon die richtige Zyklenzahl für einen MUL 
eingegeben hat. Und in diesem Fall ist es eben schneller, den MUL nicht 
zu benutzen.

von Hundertvolt (Gast)


Lesenswert?

Okay, Danke so weit!!

Wollte halt sicher gehen, dass ich nicht irgendwo etwas vergessen habe 
einzustellen und nur deshalb da kein MUL benutzt wird.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

hmmm... für den Testfall
1
unsigned short mal15 (unsigned short a)
2
{
3
    return a*15;
4
}

bekomme ich mit -O2
1
mal15:
2
  mov r18,r24   ;  25  *movhi/1  [length = 2]
3
  mov r19,r25
4
  swap r18   ;  30  *ashlhi3_const/5  [length = 6]
5
  swap r19
6
  andi r19,0xf0
7
  eor r19,r18
8
  andi r18,0xf0
9
  eor r19,r18
10
  sub r18,r24   ;  8  subhi3/1  [length = 2]
11
  sbc r19,r25
12
  mov r24,r18   ;  22  *movqi/1  [length = 1]
13
  mov r25,r19   ;  23  *movqi/1  [length = 1]
14
  ret   ;  28  return  [length = 1]

und mit -Os
1
mal15:
2
  ldi r22,lo8(15)   ;  8  *movhi/4  [length = 2]
3
  ldi r23,hi8(15)
4
  rcall __mulhi3   ;  9  *mulhi3_call  [length = 1]
5
  ret   ;  30  return  [length = 1]

Für Optimierung auf Größe dürfte das unschlagbar sein (wenn man mehr als 
ein Aufruf von __mulhi3 im Code hat. Aber das kann gcc nicht global 
wissen, da er immer nur modulweise sieht) -- bis auf die Tatsache, daß 
in avr-gcc noch keine Tail-Calls drine sind (rcall+ret = rjmp)

Die Optimierung nach Speed sieht auch verdächtig flott aus (12 Ticks), 
da dürfte ne "normale" Multiplikation kaum mitkommen...

Johann

p.s. seltsamerweise wird's mit -O2 für den ATmega32 schlechter, 
nämlich 16 Ticks (oben war nur -mmcu=avr2 gesagt)
1
mal15:
2
  movw r18,r24   ;  27  *movhi/1  [length = 1]
3
  lsl r18   ;  35  *ashlhi3_const/2  [length = 2]
4
  rol r19
5
  add r18,r24   ;  8  *addhi3/1  [length = 2]
6
  adc r19,r25
7
  movw r20,r18   ;  28  *movhi/1  [length = 1]
8
  lsl r20   ;  34  *ashlhi3_const/4  [length = 4]
9
  rol r21
10
  lsl r20
11
  rol r21
12
  add r20,r18   ;  10  *addhi3/1  [length = 2]
13
  adc r21,r19
14
  movw r24,r20   ;  33  *movhi/1  [length = 1]
15
  ret   ;  31  return  [length = 1]

Die Kostenberechnung in GCC ist eben manchmal etwas esotherisch...

von (prx) A. K. (prx)


Lesenswert?

Johann L. schrieb:

> Die Optimierung nach Speed sieht auch verdächtig flott aus (12 Ticks),
> da dürfte ne "normale" Multiplikation kaum mitkommen...

9 Takte und funktioniert bei jedem uint8 Multiplikator:
1
    ldi   r31, 15
2
    mul   r25, r31
3
    mov   r25, r0
4
    mul   r24, r31
5
    add   r25, r1
6
    mov   r24, r0
7
    clr   r1
8
    ret

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


Lesenswert?

A. K. schrieb:

> 9 Takte und funktioniert bei jedem uint8 Multiplikator:

GCC kann aber nur Multiplikanden gleicher Breite multiplizieren.

von (prx) A. K. (prx)


Lesenswert?

Aber er kann erkennen, dass einer der beiden Operanden eine Konstante 
0..255 ist. Sowas macht er ja an beliebig vielen Stellen.

Nur ist möglicherweise die Kostenkalkulation der mul vs. shift/add/sub 
Optimierung nicht sonderlich abhängig von der Zielmaschine. Geht 
vielleicht sogar davon aus, dass alles was heute rumschwirrt einen 
Barrel-Shifter hat und für int/unsigned nur einen Befehl braucht.

Und wenn diese "Optimierung" mittendrin erst einmal vollbracht ist, dann 
kann auch das beste Backend das nicht mehr gerade biegen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

A. K. schrieb:
> Johann L. schrieb:
>
>> Die Optimierung nach Speed sieht auch verdächtig flott aus (12 Ticks),
>> da dürfte ne "normale" Multiplikation kaum mitkommen...
>
> 9 Takte und funktioniert bei jedem uint8 Multiplikator:
>
>
1
>     ldi   r31, 15
2
>     mul   r25, r31
3
>     mov   r25, r0
4
>     mul   r24, r31
5
>     add   r25, r1
6
>     mov   r24, r0
7
>     clr   r1
8
>

Ok, überzeugt :-)

Bau's ein in avr-gcc:

1) mulhi3 akzeptiert nicht nur GPRs, sondern auch Konstanten
2) die Konstante kommt per copy_to_mode_reg in ein GPR und man
   expandiert je nach HI zum alten *mulhi3_enh oder für QI zu einer
3) Neue Insn *mulhi3_enh_zerox
1
(define_insn "*mulhi3_enh_zerox"
2
  [(set (match_operand:HI 0 "register_operand" "=&r")
3
        (mult:HI (match_operand:HI 1 "register_operand" "r")
4
                 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
5
  "AVR_HAVE_MUL"
6
  ...

Ich hab kein FSF assignment, würd also nix bringen wenn ichn Patch 
machen würd.

Johann

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


Lesenswert?

Johann L. schrieb:

> Ich hab kein FSF assignment, würd also nix bringen wenn ichn Patch
> machen würd.

Naja, das kannste aber ruhig mal machen, gemessen daran, dass du
einigermaßen Durchblick da hast.  Ist für einen Deutschen übrigens
komplett risikofrei :), wir können nämlich aus Prinzip ein Copyright
niemandem abtreten.  Wenn's die FSF also glücklich macht...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Johann L. schrieb:
>
>> Ich hab kein FSF assignment, würd also nix bringen wenn ichn Patch
>> machen würd.
>
> Naja, das kannste aber ruhig mal machen, gemessen daran, dass du
> einigermaßen Durchblick da hast.  Ist für einen Deutschen übrigens
> komplett risikofrei :), wir können nämlich aus Prinzip ein Copyright
> niemandem abtreten.  Wenn's die FSF also glücklich macht...

Meine anderen Patches gammeln auch nur in irgendwelchen MLs rum, ausser 
für
   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18145
den hat Eric glaub in seiner Win-Distri drinne, aber in mainline ist er 
auch nicht.

Heisst konkret: wenn die FSF es irgendwann mal gebacken bekommt, kann 
man die ganzen Patches nochmal komplett neu schreiben weil man sie gegen 
trunk haben will und mit den olle Kamellen kaum mehr was anfangen kann. 
Also doppelte Arbeit, was ich nicht einsehe.

Eric hatte mal angedeutet, daß die FSF nicht sooo flott ist. Er wartet 
immerhin schon rund 3 Jahren oder so...

Johann

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


Lesenswert?

Johann L. schrieb:

> Eric hatte mal angedeutet, daß die FSF nicht sooo flott ist. Er wartet
> immerhin schon rund 3 Jahren oder so...

Nein, die FSF ist da so lahm nicht.  Meine ,Assignments' damals haben
trotz des Postwegs alles in allem keine 2 Monate gebraucht.  Wenn du
das also mal machen willst, damit deine Patches denn auch eine Chance
haben, überhaupt in den Code einzufließen (ein wenig ,,Durchboxen''
muss man das dann trotzdem noch), dann sollstest du diesen Kram mal
anschieben.

Was bei Eric gedauert hat (und wohl immer noch dauert) ist, all diesen
Kram durch die Rechtsabteilung bei Atmel zu bekommen, damit die erstmal
zustimmen, dass für ihn und seine Kollegen das FSF copyright assignment
überhaupt erst beantragt werden darf.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Johann L. schrieb:
>
>> Eric hatte mal angedeutet, daß die FSF nicht sooo flott ist. Er wartet
>> immerhin schon rund 3 Jahren oder so...
>
> Nein, die FSF ist da so lahm nicht.  Meine ,Assignments' damals haben
> trotz des Postwegs alles in allem keine 2 Monate gebraucht.  Wenn du
> das also mal machen willst, damit deine Patches denn auch eine Chance
> haben, überhaupt in den Code einzufließen (ein wenig ,,Durchboxen''
> muss man das dann trotzdem noch), dann sollstest du diesen Kram mal
> anschieben.

Das war Anfang Januar. Angeblich wollten sie was schicken.
Als nach über 3 Monaten noch nix angekommen war, hab ich mal vorsichtig 
nachgefragt...keine Antwort. Soviel zu dem Thema.

> Was bei Eric gedauert hat (und wohl immer noch dauert) ist, all diesen
> Kram durch die Rechtsabteilung bei Atmel zu bekommen, damit die erstmal
> zustimmen, dass für ihn und seine Kollegen das FSF copyright assignment
> überhaupt erst beantragt werden darf.

Ok, wenn das Dummheit von Atmel ist, selber Schuld.
Mit den Worten von Onkel Wicki:

>> [...] and chip manufacturers today consider a gcc port almost
>> essential to the success of an architecture.

Johann

von Johann L. (gjlayde) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hier ist das Patch. Vielleicht kannst du ja was damit anfangen...

Johann

von Martin Thomas (Gast)


Lesenswert?

Finde es schade, dass zumindest einige von Georg-Johann L.s 
Verbessungsvorschlägen augenscheinlich ungenutzt bleiben. Man könnte 
doch  auf dem "kleinen Dienstweg" ohne FSF- und Atmel-Bürokratie eine 
Liste von ausstehenden nicht-offiziellen Patches (binutils, compiler, 
libc) inkl. Links (evtl. in ein testing-UVZ von Jörgs "BSD-Sammlung") 
und ein paar erklärenden Worten in die avr-libc Dokumentation aufnehmen. 
Das wäre eine recht prominente Stelle und auch für diejenigen gut 
auffindbar, die nicht alle relevanten Mailinglisten, Foren und 
Bugtracker mitverfolgen aber dennoch etwas über den WinAVR Tellerrand 
schauen möchten.

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


Lesenswert?

Johann L. schrieb:

> Das war Anfang Januar. Angeblich wollten sie was schicken.
> Als nach über 3 Monaten noch nix angekommen war, hab ich mal vorsichtig
> nachgefragt...keine Antwort. Soviel zu dem Thema.

Dann solltest du mal penetrant werden.  Dummerweise steht und fällt
die Bearbeitungsqualität dieses Jobs wohl mit dem Sekretär/der
Sekretärin, die diesen Kram offenbar in Teilzeit erledigt.  Hab ich
damals wohl Glück gehabt, bei mir lief das sehr reibungslos.

> Ok, wenn das Dummheit von Atmel ist, selber Schuld.

Naja, Rechtsabteilung halt.  Das ist bei einem derartigen VEB wohl
sowas wie ein Staat im Staate. :-(   Die Inschenöre hätten das sicher
lieber heute als morgen im offiziellen Tree drin, es macht sicher
keinen Spaß, den ganzen AVR32-Krams außerhalb zu pflegen.

Außerdem ist natürlich auch irgendwie Sturheit der FSF im Spiel.  Dieses
Bestehen auf der Copyright-Abtretung ist nicht völlig verständlich, das
würde gut auch ohne dem gehen.

Das blöde ist, dass du deinen Patch nicht einfach jemandem anders in
die Hand drücken kannst, damit er das in seinem Namen einarbeitet,
denn die GNU-Leute legen ausdrücklichen Wert darauf, dass die jeweils
vorgebrachten Änderungen auch das geistige Eigentum desjenigen sind,
der sie vorbringt.

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


Lesenswert?

Martin Thomas schrieb:

> Man könnte
> doch  auf dem "kleinen Dienstweg" ohne FSF- und Atmel-Bürokratie eine
> Liste von ausstehenden nicht-offiziellen Patches (binutils, compiler,
> libc) inkl. Links (evtl. in ein testing-UVZ von Jörgs "BSD-Sammlung")
> und ein paar erklärenden Worten in die avr-libc Dokumentation aufnehmen.

Hmm, im Prinzip gibt's ja schon zwei Stellen dafür.  Leider bin ich
selbst in letzter Zeit ziemlich ins Hintertreffen mit den BSD-Patches
gekommen, aber das wäre die erste Stelle.  Die zweite ist das CVS
von WinAVR auf sourceforge.net.

Ja, wenn das mit Johanns FSF-Papierkram partout nicht geht, könnte
man seine Patches auf diesem Wege zumindest überhaupt einem größeren
Publikum zu Gute kommen lassen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Martin Thomas schrieb:
>
>> Man könnte
>> doch  auf dem "kleinen Dienstweg" ohne FSF- und Atmel-Bürokratie eine
>> Liste von ausstehenden nicht-offiziellen Patches (binutils, compiler,
>> libc) inkl. Links (evtl. in ein testing-UVZ von Jörgs "BSD-Sammlung")
>> und ein paar erklärenden Worten in die avr-libc Dokumentation aufnehmen.
>
> Hmm, im Prinzip gibt's ja schon zwei Stellen dafür.  Leider bin ich
> selbst in letzter Zeit ziemlich ins Hintertreffen mit den BSD-Patches
> gekommen, aber das wäre die erste Stelle.  Die zweite ist das CVS
> von WinAVR auf sourceforge.net.

Eric und Anatoly sind ja fleissig Patches am sammeln.
Das blöde ist, daß man so irgendwann nicht mehr damit arbeiten kann. Man 
kann nicht ein Patch auf einem anderen basieren lassen, es gibt keine 
Weiterentwicklung, und wenn Eric die Patches nicht in die Win-Distri 
einbauen würde, gäb's nicht ein mal nen live-Test und Bugs blieben 
unentdeckt.

Wenn ich heute ein Patch gegen trunk mache, weiß ich, daß sich das mit 
zig anderen Patches in die Wolle bekommen wird...

Und weil es keine Entwicklung auf gcc-Ebene gibt, weiß man nie genau, 
welche Patches wo rumschwirren, sich widersprechen, oder schon 
existieren, so daß man evtl. Arbeit doppelt machen würde. Beispiel 
builtins.

Größere Patches wie die Bit-Optimierungen konflikten mit anderen, und an 
64-Bit Instruktionen oder Tail-Call-Optimierung ist momentan nicht zu 
denken. Nicht aus technischen Gründen, sondern aus organisatorischen.

Johann

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.