AVR Inline-Optimierung

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: AVR Inline-Optimierung

Beitrag von Timm Thaler »

FPK hat geschrieben:Kurzform: Der Typ des Ergebnisses einer Operation hängt immer von den Typen der Operanden ab, bei arithmetischen Operationen gilt eigentlich immer, dass der Typ gewählt wird, in den beiden Operanden passen, bei word*word ist das eben word, bei word*integer ist das longint. Damit ist klar, dass word*integer eine 32 Bit Operation verursacht.


Naja, ganz so "klar" ist das nicht:

Code: Alles auswählen

# [42] c_i32 := a_i16 * b_i16;
   lds   r18,(U_sMT_MATH_ss_A_I16)
   lds   r21,(U_sMT_MATH_ss_A_I16+1)
   lds   r22,(U_sMT_MATH_ss_B_I16)
   lds   r23,(U_sMT_MATH_ss_B_I16+1)
   mul   r18,r22
   mov   r19,r0
   mov   r20,r1
   mul   r21,r22
   add   r20,r0
   mul   r18,r23
   add   r20,r0
   clr   r1
   mov   r21,r20
   mov   r18,r1
   sbrc   r20,7
   com   r18
   mov   r20,r18
   sts   (U_sMT_MATH_ss_C_I32),r19
   sts   (U_sMT_MATH_ss_C_I32+1),r21
   sts   (U_sMT_MATH_ss_C_I32+2),r18
   sts   (U_sMT_MATH_ss_C_I32+3),r20


Ist ja nicht so, dass ich mich nicht damit beschäftigt hätte. Besonders lustig ist dann sowas:

Code: Alles auswählen

# [42] b_u16 := 15 * a_u16;
   lds   r18,(U_sMT_MATH_ss_A_U16)
   lds   r19,(U_sMT_MATH_ss_A_U16+1)
   mov   r20,r1
   mov   r21,r1
   ldi   r22,15
   mov   r23,r1
   mov   r24,r1
   mov   r25,r1
   call   fpc_mul_longint
   sts   (U_sMT_MATH_ss_B_U16),r22
   sts   (U_sMT_MATH_ss_B_U16+1),r23


Ich denke es liegt eher daran, dass da jemand dankenswerterweise für einige Typkonstellationen schon gut in Asm optimiert hat, während es für andere Konstallationen diese Optimierung noch nicht gibt und der Compiler dann halt auf seine Standardroutinen zugreift.

FPK hat geschrieben:Stimmt für trunk jedenfalls nicht mehr:


Stimmt für uint16 nicht. Bei int16, uint32, int32 macht er durchaus das Shift über alle 8 Bits für alle 2 oder 4 Bytes. Ich denk mir das doch nicht aus.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: AVR Inline-Optimierung

Beitrag von Mathias »

m PC möchte ich auch nicht (mehr) mit Assembler rumfummeln. Allerdings konnte man nur so in Turbo-Pascal einen Grafikbildschirm mehr als 16 Farben bekommen. ;-)
Dies stimmt nicht, es ging ohne Assembler, auch wen nicht so effizient.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

FPK
Beiträge: 65
Registriert: Mi 21. Mai 2008, 19:38
Wohnort: Erlangen

Re: AVR Inline-Optimierung

Beitrag von FPK »

Timm Thaler hat geschrieben:
FPK hat geschrieben:Kurzform: Der Typ des Ergebnisses einer Operation hängt immer von den Typen der Operanden ab, bei arithmetischen Operationen gilt eigentlich immer, dass der Typ gewählt wird, in den beiden Operanden passen, bei word*word ist das eben word, bei word*integer ist das longint. Damit ist klar, dass word*integer eine 32 Bit Operation verursacht.


Naja, ganz so "klar" ist das nicht:

Code: Alles auswählen

# [42] c_i32 := a_i16 * b_i16;
   lds   r18,(U_sMT_MATH_ss_A_I16)
   lds   r21,(U_sMT_MATH_ss_A_I16+1)
   lds   r22,(U_sMT_MATH_ss_B_I16)
   lds   r23,(U_sMT_MATH_ss_B_I16+1)
   mul   r18,r22
   mov   r19,r0
   mov   r20,r1
   mul   r21,r22
   add   r20,r0
   mul   r18,r23
   add   r20,r0
   clr   r1
   mov   r21,r20
   mov   r18,r1
   sbrc   r20,7
   com   r18
   mov   r20,r18
   sts   (U_sMT_MATH_ss_C_I32),r19
   sts   (U_sMT_MATH_ss_C_I32+1),r21
   sts   (U_sMT_MATH_ss_C_I32+2),r18
   sts   (U_sMT_MATH_ss_C_I32+3),r20



Wo ist das Problem? integer*integer ergibt integer, also 16 Bit Multiplikation und dann auf 32 Bit erweitert.

Ist ja nicht so, dass ich mich nicht damit beschäftigt hätte. Besonders lustig ist dann sowas:

Code: Alles auswählen

# [42] b_u16 := 15 * a_u16;
   lds   r18,(U_sMT_MATH_ss_A_U16)
   lds   r19,(U_sMT_MATH_ss_A_U16+1)
   mov   r20,r1
   mov   r21,r1
   ldi   r22,15
   mov   r23,r1
   mov   r24,r1
   mov   r25,r1
   call   fpc_mul_longint
   sts   (U_sMT_MATH_ss_B_U16),r22
   sts   (U_sMT_MATH_ss_B_U16+1),r23



Das sollte behoben werden, Bugreport und fertig. Wenn Du jedes Mal da in Assembler drumherum codest, hat keiner was davon.

FPK hat geschrieben:Stimmt für trunk jedenfalls nicht mehr:


Stimmt für uint16 nicht. Bei int16, uint32, int32 macht er durchaus das Shift über alle 8 Bits für alle 2 oder 4 Bytes. Ich denk mir das doch nicht aus.


Wie gesagt Beispielcode in eine Bugreport, dann kümmert sich über kurz oder lang jemand darum, oder svn revision 37606 anschauen wie es geht und selber im Compiler umsetzen, ist in diesem Fall kein Hexenwerk, nur bisschen Fleißarbeit.

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: AVR Inline-Optimierung

Beitrag von kupferstecher »

FPK hat geschrieben:Registernutzung ist eine Sache, die man vielleicht in den Griff kriegt. Aber man kann eben in Assembler unendlich Gemeinheiten schreiben, die den Compiler bzw. den Optimierer aus dem Tritt bringen, angefangen bei Aliasing oder unerwarteten Stackmanipulationen.

Das gleiche gilt doch bei allem Inlineassemblercode. Auch wenn er in eine eigene Funktion gepackt wird, kann er in der aufrufenden Ebene den Stack durcheinanderbringen, etc. Oder fungiert jeder Funktionsaufruf als Barriere für Optimierungen? Das kann ich mir auch nicht vorstellen.
Bzgl. Stack, der Stack darf ja sowieso nicht manipuliert werden, sonst funktioniert auch der Rücksprung aus der Funktion nicht mehr. Aliasing ist ein Problem, jedoch auch wenn man eine Variable in der Nicht-Inline-Funktion verändert.
Wenn man Assemblerblöcke schreibt, muss man sowieso wissen, was man tut, ein paar zusätzliche Regeln für Inlineassembler wären daher m.M.n. schon in Ordnung.

Ich bin deswegen auch der Meinung: der Nutzer einer Entwicklungssystem darf kein Assembler benötigen, falls doch, ist was am Compiler/der Sprache falsch (natürlich sollte auch die Laufzeitbibliothek so wenig wie möglich Assembler enthalten, leider kommt man da manchmal nicht drumherum).

Das sehe ich nicht so. In zeitkritischen Anwendungen kommt es manchmal auf einzelne Takte an. Bspw. wenn ein Interrupt alle 100 Takte aufgerufen werden soll, kann es sein, dass der Compiler keinen kompakt genugen Code liefert. Klar soll man Inlineassembler nur in Spezialfällen benötigen. Aber auch gerade wenn der Compiler in der Entwicklung noch nicht so weit ist, lassen sich mit dem Inline-Assembler schnell Probleme umschiffen (auch wenns ggf. murks ist).

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: AVR Inline-Optimierung

Beitrag von Timm Thaler »

kupferstecher hat geschrieben:Das sehe ich nicht so. In zeitkritischen Anwendungen kommt es manchmal auf einzelne Takte an. Bspw. wenn ein Interrupt alle 100 Takte aufgerufen werden soll, kann es sein, dass der Compiler keinen kompakt genugen Code liefert. Klar soll man Inlineassembler nur in Spezialfällen benötigen. Aber auch gerade wenn der Compiler in der Entwicklung noch nicht so weit ist, lassen sich mit dem Inline-Assembler schnell Probleme umschiffen...


Normalerweise optimiert der Compiler schon sehr gut, ich staune da mitunter. Da läßt sich auch mit Assembler selten noch mehr rausholen. Man kann es dem Compiler aber durch "günstiges" Programmieren leichter machen.

Zum Beispiel hängt die Geschwindigkeit einer Interrupt-Routine schon davon ab, ob man darin verwendete Variablen extern oder intern deklariert. Extern wird der Stackframe kleiner, aber es gibt mehr ld+st. Intern wird zwar mehr gepushed und gepoppt, aber dafür dann schneller gerechnet.

Oder Formeln ausschreiben. Letztens einen Artikel gelesen, dass man in C Formeln möglichst in die einzelnen Rechenschritte aufteilen soll. Da sag ich doch: Nehmt halt eine ordentliche Programmiersprache, da kann man die Formel in einem Stück schreiben, und der Compiler macht - meist - was Vernünftiges draus.

FPK
Beiträge: 65
Registriert: Mi 21. Mai 2008, 19:38
Wohnort: Erlangen

Re: AVR Inline-Optimierung

Beitrag von FPK »

kupferstecher hat geschrieben:
FPK hat geschrieben:Registernutzung ist eine Sache, die man vielleicht in den Griff kriegt. Aber man kann eben in Assembler unendlich Gemeinheiten schreiben, die den Compiler bzw. den Optimierer aus dem Tritt bringen, angefangen bei Aliasing oder unerwarteten Stackmanipulationen.

Das gleiche gilt doch bei allem Inlineassemblercode. Auch wenn er in eine eigene Funktion gepackt wird, kann er in der aufrufenden Ebene den Stack durcheinanderbringen, etc. Oder fungiert jeder Funktionsaufruf als Barriere für Optimierungen? Das kann ich mir auch nicht vorstellen.


Was sich während/durch eines Funktionsaufrufs ändern darf und was nicht ist normalerweise klar im ABI definiert und relativ beschränkt.

Ich bin deswegen auch der Meinung: der Nutzer einer Entwicklungssystem darf kein Assembler benötigen, falls doch, ist was am Compiler/der Sprache falsch (natürlich sollte auch die Laufzeitbibliothek so wenig wie möglich Assembler enthalten, leider kommt man da manchmal nicht drumherum).

Das sehe ich nicht so. In zeitkritischen Anwendungen kommt es manchmal auf einzelne Takte an. Bspw. wenn ein Interrupt alle 100 Takte aufgerufen werden soll, kann es sein, dass der Compiler keinen kompakt genugen Code liefert.


Gerade bei einem MCU, der eigentlich für compilierte Sprachen gemacht ist, kommt man da schnell an die Grenzen und der Compiler ist doch besser.
Klar soll man Inlineassembler nur in Spezialfällen benötigen. Aber auch gerade wenn der Compiler in der Entwicklung noch nicht so weit ist, lassen sich mit dem Inline-Assembler schnell Probleme umschiffen (auch wenns ggf. murks ist).


Naja, ein Bugreport dauert max. 10 min, das sollte einem ein OSS-Compiler schon wert sein. Dass nicht jeder einen entsprechenden Compiler-Patch erstellen kann, ist klar, wobei das bei FPC für Pascal-Programmierer noch am einfachsten sein sollte.

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: AVR Inline-Optimierung

Beitrag von Timm Thaler »

1. Ist eine nicht implementierte oder nicht optimierte Funktion schon ein Bug? Sehen vielleicht nicht alle so.
2. Existiert der Avr Compiler zwar schon einige Jahre, hat aber erst in letzter Zeit so richtig Funktionen bekommen, wie mir scheint.
3. Würde ich schon gern zur Weiterentwicklung beitragen. Ich hab 15+ Jahre Erfahrung mit Asm auf Avr. Aber ich will a) keine falschen oder unzureichend getesteten Funktionen einbauen und b) nix kaputtmachen.

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: AVR Inline-Optimierung

Beitrag von kupferstecher »

FPK hat geschrieben:Was sich während/durch eines Funktionsaufrufs ändern darf und was nicht ist normalerweise klar im ABI definiert und relativ beschränkt.

Das gilt ja bereits für eine Assemblerfunktion. Wie gesagt, ich sehe nicht, welche zusätzlichen Anforderungen an eine Inlineassemblerfunktion zu stellen wären. Deshalb die Nachfrage.

Naja, ein Bugreport dauert max. 10 min, das sollte einem ein OSS-Compiler schon wert sein. Dass nicht jeder einen entsprechenden Compiler-Patch erstellen kann, ist klar, wobei das bei FPC für Pascal-Programmierer noch am einfachsten sein sollte.

Wie Tim Thaler schon geschrieben hat, wo fängt ein Bug an und wo hört ein fehlendes Feature auf?

Hier ein Bug/Feature Request welchen ich initiiert habe. Es geht darum ob der Compiler momentan Variablenzugriffe überhaupt optimieren darf, da es an einem Volatile-Konzept fehlt.
https://bugs.freepascal.org/view.php?id=32721

Das aber nur als Beispiel, es fehlt halt noch an mehreren Ecken.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: AVR Inline-Optimierung

Beitrag von Christian »

@Florian, schön zu sehn das dich der avr immernoch "juckt"

1. gibt es für das Architektur-auswahl Problem nicht eine elegantere Lösung als compiler neu übersetzen ?
Bzw wenn man die einzeln benennnen würde analog zu crosscompilern müsste man nicht jedesmal umcompilieren (betrifft arm glaub ioch auch)

2. ich kann deine Einstellung bezüglich Assembler gut verstehen, schiesslich macht man dort ein Unendliches Fehlerträchtiges Gebiet auf. Muss beim AVR Timm aber recht geben, auf der Architektur macht Assembler mehr Sinn als auf allen anderen, da man Taktgenau steuern kann wann was passiert.
Und hier ist Pascal gerade im Vorteil ich find Assembler und Pascal passen immer sher gut zusammen in C wirkt das immer artfremd. Vllt sollte man hier etwas auf Bascom schauen dort ist das mischen von Basic und Assembler sehr gut gelungen.
Man muss natürlich Aufwand/Nutzen abwägen Avr ist meiner Meinung nach schon wieder fast überholt. Und bei Cortex-M* und ESPxx braucht man schon wider nichts mehr Taktgenau da man eh ein paar tausend Takte warten muss bis ein Port getoggelt wird.

@Timm, glaub du übertriebst es ein klein wenig mit Diskussion, wenn dir der Compiler Bauer Nr 1 anbietet sich drum zu kümmern wenn du nur nen Bugreport erstellst, dann mach doch :)
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: AVR Inline-Optimierung

Beitrag von Mathias »

Man muss natürlich Aufwand/Nutzen abwägen Avr ist meiner Meinung nach schon wieder fast überholt.

Wieso sollte der überholt sein, für einfache kleine Sachen ist dies ein sehr handlicher MC. Und nicht vergessen, fast das ganze Arduino-Zeugs verwendet einen AVR.
Auch ist er noch in ein DIP-Gehäuse erhältlich.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: AVR Inline-Optimierung

Beitrag von Timm Thaler »

Christian hat geschrieben: Avr ist meiner Meinung nach schon wieder fast überholt. Und bei Cortex-M* und ESPxx ...


Dafür dass der Avr schon seit Jahren totgesagt wird, weil ja 32bitter alles besser können, hält er sich erstaunlich lange. Und dank Arduino bin ich mir ziemlich sicher, dass es Typen wie den 328 auch in einigen Jahren noch geben wird. Kann man das von Cortex-M und ESP auch annehmen?

Christian hat geschrieben: @Timm, glaub du übertriebst es ein klein wenig mit Diskussion, wenn dir der Compiler Bauer Nr 1 anbietet sich drum zu kümmern wenn du nur nen Bugreport erstellst, dann mach doch :)


Gern. Da hätte ich aber viele Baustellen.

Woher soll ich wissen, dass FPK für FreePascalKompilerbauer steht... :wink:

Bisher war ich mir eher unsicher, wie intensiv Avr embedded überhaupt vorangetrieben wird. Das vor Monaten angefragte direkte Lesen von Konstanten oder Strings aus dem Flash ohne Umweg über den Sram ist meines Wissens nach nicht umgesetzt. Dazu hatte ich auch Assemblercode reingestellt.

Wird beim Bugreport nochmal zwischen Bug und Featurerequest unterschieden? Ich kann mich nicht an eine Auswahl erinnern, hab aber gerade keinen Zugriff drauf.

Btw: Mein erster Bugreport endete damit, dass erstmal die ISR kaputt waren. Da wird man vorsichtig... :oops:

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: AVR Inline-Optimierung

Beitrag von Mathias »

Dafür dass der Avr schon seit Jahren totgesagt wird, weil ja 32bitter alles besser können, hält er sich erstaunlich lange. Und dank Arduino bin ich mir ziemlich sicher, dass es Typen wie den 328 auch in einigen Jahren noch geben wird. Kann man das von Cortex-M und ESP auch annehmen?
Das denke ich auch.
Wie sieht es mit dem Stromverbrauch aus ?
Was braucht weniger, ein AVR oder Cortex, ESP, ARM ?

So nebenbei, gibt es bei den AVR noch Neuentwicklungen ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: AVR Inline-Optimierung

Beitrag von Christian »

Und dank Arduino bin ich mir ziemlich sicher, dass es Typen wie den 328 auch in einigen Jahren noch geben wird. Kann man das von Cortex-M und ESP auch annehmen?

Auf jeden Fall, bei den Arms gibts nicht nur einen Hersteller sondern zig. Atmel hat keine eigenen Chipfabriken mehr und wurde auch das erste mal verkauft. Die Cortex Mx haben wesentlich bessere Periferie, viel mehr Leistung, mehr Flash und kosten meisst ein drittel der AVR´s
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: AVR Inline-Optimierung

Beitrag von Mathias »

Aber ich hoffe trotzdem, das Lazarus für AVR weiter entwickelt wird. Es wird sogar für 8088er entwickelt, obwohl man diese nicht mal mehr kaufen kann.

Wie sieht es mit dem Stromverbrauch aus ?
Was braucht weniger, ein AVR oder Cortex, ESP, ARM ?
Dies wäre trotzdem interessant zu wissen.

Irgendwie bringt man Lazarus auch auf einem ARM zum laufen, aber dies geht momentan nicht so einfach, wie für den AVR. Ausser den Raspi.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: AVR Inline-Optimierung

Beitrag von Timm Thaler »

Dass es verschiedene Anbieter für Cortex M gibt nützt mir gar nichts, wenn der Hersteller "meines" Chips für den ich ein Design gemacht habe in 2 Jahren diesen Chip nicht mehr herstellt.

Den ATmega8 setze ich seit 12 Jahren ein und könnte ihn problemlos durch einen 328 ersetzen. Der Bcm2837 der im Rpi 3 sitzt ist bereits abgekündigt, wenn ich das letztens richtig gelesen habe.

Antworten