(PS: sry, handy ist blöd zum schreiben )
Fazit:
Es lonht sich in jedem Falle, ab und zu in den Assembler Code reinzuschauen, sofern es notwenidig ist und man zeitkritische Anpassungen machen muss.
Siro
PS: zudem ist mir heute das zweite Mal die IDE abgestürzt. Sie lässt sich vermeintlich im Taskmanager beenden, das tut sie aber nicht.
Ich muss tatsächlich den Rechner neu starten. Immer beim Umstellen der Projekt Properties.
(PS: sry, handy ist blöd zum schreiben )
Hallo zusammen,
ein kleines Update der beschriebenen Problematik
"Multiplikation verhindern"
Ich wollte eben einen kleines PIC Progrämmchen schreiben
und bin unter anderem wieder über die Multiplikation mit 3 gestoßen.
Der ursprünglich "erfolgreiche" Code mit
count = (count << 1) + count;
war ja am kürzesten,
doch plötzlich weigert sich der Compiler einen entsprechenden Code zu erzeugen.
er benutzt generell ein Unterprogramm mit einer Multiplikation...
Nach einigem herumprobieren habe ich nun festgestellt, dass ich eine neue Version vom XC8 auf dem Rechner habe
und genau da liegt das Problem.
V2.00 erzeugt "guten" kompakten Code
V2.10 ungünstig, Berechnung generell über Unterprammaufruf Multiplikation
V2.20 ungünstig, Berechnung generell über Unterprammaufruf Multiplikation
Ich habe es auch mit verschiedenen Optimierungseinstellungen probiert,
leider bisher ohne Erfolg.
Anbei:
hat sich auch mein Ausschiebecode für meine RGB LEDs verändert und funktioniert auch nicht mehr.
Hier treten plötzlich erheblich längere Zeiten auf, weil der erzeugt Code anders und langsamer ist.
Das stellt natürlich generell ein riesen Problem dar:
Wenn man solch zeitkritischen Code in C (oder generell in einer Hochsprache) implementiert
weiss man nicht was der Compiler daraus macht.
Durch ein Compilerupdate hat dies unter Umständen katastrophale Folgen.
Im Prinzip holt mich ein "ehemaliges" Problem wieder ein. Siehe Thread:
https://www.roboternetz.de/community...line-Assembler
Da hatte ich meinen Assembler Code in C umgesetzt....
SiroCode:Compiler ist der XC8 Version V2.00 ! // damit keine Multiplikation verwendet wird: ! count = (count << 1) + count; // 3 Bytes pro Led RGB 0x463: LSLF count, W 0x464: ADDWF count, W 0x465: MOVWF __pcstackCOMMON 0x466: MOVF __pcstackCOMMON, W 0x467: MOVWF count ------------------- Compiler ist der XC8 Version V2.10 79: // damit keine Multiplikation verwendet wird: 80: count = (count << 1) + count; // 3 Bytes pro Led RGB !! er nimmt einen Multiplikations 001F 3003 MOVLW 0x3 0020 00C6 MOVWF 0x46 0021 0846 MOVF 0x46, W 0022 00C2 MOVWF multiplicand 0023 084B MOVF count, W 0024 20A4 CALL 0xA4 0025 00C7 MOVWF 0x47 0026 0847 MOVF 0x47, W 0027 00CB MOVWF count ------------------------------ Compiler ist der XC8 Version V2.20 305: // damit keine Multiplikation verwendet wird: 306: count = (count << 1) + count; // 3 Bytes pro Led RGB 03A9 3003 MOVLW 0x3 03AA 00F4 MOVWF i 03AB 0874 MOVF i, W 03AC 00F0 MOVWF __pcstackCOMMON 03AD 087A MOVF count, W 03AE 3185 MOVLP 0x5 03AF 25D0 CALL 0x5D0 03B0 3183 MOVLP 0x3 03B1 00F5 MOVWF counter 03B2 0875 MOVF counter, W 03B3 00FA MOVWF count
Geändert von Siro (15.08.2020 um 22:38 Uhr)
Hallo Siro!
Mal anders gedacht:
Kannst Du nicht an der einen Stelle Inline-Assembler nutzen?
MfG
Ja Moppi, das kann ich natürlich und das mache ich jetzt auch.
Assembler scheint aber mehr oder minder verpöhnt innerhalb einer Hochsprache und darum versuche ich es auch, soweit als möglich, zu vermeiden.
Das Meiste kann man ja wirklich in Hochsprache erledigen, aber manchmal geht das halt doch nicht.
Ich war aber wirklich erstaunt, dass die neue Compilerversion doch so erheblich unterschiedlichen Code erzeugt.
Die Compilerbauer haben ja jegliche Freiheit, es geht nur darum den Code von Hochsprache auf Assemblercode umzusetzen,
wie er das macht ist nicht unbedingt vorgeschrieben. Der Code ist ja funktionell auch richtig.
nur das Timing halt nicht. Durch die eng gesteckten Parameter bei den WS2812 RGB Leds wird das tatsächlich zum Problem..
Die Multiplikation wollte ich natürlich auch vermeiden, da mein kleiner PIC nur 512 Byte bzw. Programwords hat.
Jetzt zu versuchen den C Code wieder so hinzufrickeln dass er evtl. keine Multiplikation daraus macht, gibt nicht wirklich Sinn,
beim nächsten Update könnte das dann wieder anders aussehen. Daher also "back to the roots (Assembler)"
[nächtliches edit]
Nun kann ich mit dem 6 poligen PIC10F322 auch RGB Leds steuern. Timing stimmt dank ASM.
Siro
Geändert von Siro (16.08.2020 um 02:30 Uhr)
10 Jahre habe ich nur Maschinensprache und mit Assembler programmiert. Das sind die typischen Pro's für Assembler. Also auch Inline.
Übrigens habe ich noch nie davon gehört, dass Inline-Assembler verpönt sei. Ich hatte in den 90gern viel Kontakt auch zu Mitarbeitern bei SAP und habe mich da also viel in der Sphäre "rumgetrieben", inkl. Usenet. Ich habe das eigentlich gegenteilig kennengelernt, nämlich genau so, dass man dann sehr wohl Inline-Assembler auch nutzt. Kann vielleicht sein, dass sich das im Laufe der Zeit etwas geändert hat, weil heute viel systemübergreifend gemacht wird. Damals waren Cross-Compiler die Ausnahme.
MfG
interessant....!
was macht/braucht er hier...?
t = cnt;
cnt+=cnt;
cnt+=t;
PS,
gibt es evt compiler options zur Optimierung, die man disablen kann ( -O0 ) ?
@HaWe:
XC8 Compiler V2.00
t = cnt;
0x8E: MOVF cnt, W
0x8F: MOVWF 0x51
0x90: MOVF 0x51, W
cnt+=cnt;
0x92: MOVF cnt, W
0x93: MOVWF 0x51
0x94: MOVF 0x51, W
0x95: ADDWF cnt, F
cnt+=t;
0x96: MOVF t, W
0x97: MOVWF 0x51
0x98: MOVF 0x51, W
0x99: ADDWF cnt, F
---------------------------
XC8 Compiler V2.10
t = cnt;
0x89: MOVF cnt, W
0x8A: MOVWF 0x51
0x8B: MOVF 0x51, W
0x8C: MOVWF t
cnt+=cnt;
0x8D: MOVF cnt, W
0x8E: MOVWF 0x51
0x8F: MOVF 0x51, W
0x90: ADDWF cnt, F
cnt+=t;
0x91: MOVF t, W
0x92: MOVWF 0x51
0x93: MOVF 0x51, W
0x94: ADDWF cnt, F
-------------------------
Compiler XC8 V2.20
compiliert meinen inline Assembler Code garnicht mehr, er meckert....
sehr merkwürdig.
-------------------------
übrigens: einen Wert * 3 geht auch so: Manuelle Codierung
cnt = cnt * 3;
asm("movf _cnt,W");
asm("addwf _cnt,F");
asm("addwf _cnt,F");
man benötigt nichteinmal eine Zwischenvariable
Geändert von Siro (16.08.2020 um 15:07 Uhr)
@Siro
und das bedeutet jetzt...was?
Fazit:
Man weis nicht genau was für ein Code vom Compiler erzeugt wird
und der kann, je nach Version, auch völlig unterschiedlich ausfallen,
was im Normalfall aber keine wirkliche Rolle spielt. Funktional sollte man sich darauf verlassen können.
Lediglich bei sehr zeitkritischen Anwendungen und/oder wenn man Code sparen muss, sollte man sich unter Umständen den erzeugten Code mal genauer anschauen.
Ein Garant für gleichen Code bzw. Laufzeiten bei unterschiedlichen Compiler Versionen ist nicht gegeben.
Achja, wenn man Softwaredokumentation bzw. Abnahmen für Geräte benötigt, ist es in sicherheitsrelevanten Anwendungen
zwingend notwendig die gesamte Entwicklungsumgebung "einzufrieren" da durch ein Update nicht sichergestellt ist,
dass anhand der Sourcen ein identischer Code wieder hergestellt werden kann.
Siro
Lesezeichen