moinmoin!
für cnt=3 geht das ntl mit 1x shiften und 1x addieren, aber für cnt >= 4 brauchst du ja wieder Zähler und/oder eine Fallunterscheidung ob cnt gerade oer ungerade.
Aber nur interessehalber,
was macht er per
for(int i=1; i<cnt;i++) t+=x;
![]()
moinmoin!
für cnt=3 geht das ntl mit 1x shiften und 1x addieren, aber für cnt >= 4 brauchst du ja wieder Zähler und/oder eine Fallunterscheidung ob cnt gerade oer ungerade.
Aber nur interessehalber,
was macht er per
for(int i=1; i<cnt;i++) t+=x;
![]()
Geändert von HaWe (02.11.2018 um 06:46 Uhr)
Guten Morgen,
hab ich auch mal getestet:
wobei mir grad auffällt, da kommt ja was anderes raus...Code:for(i=0; i<3;i++) cnt+=cnt; // 44 Zyklen, normaler Schleifencode, wenn i ein unsigned char ist for(int i=0; i<3;i++) cnt+=cnt; // 76 Zyklen, normaler Schleifencode, weil i ein int ist,
Siro
Geändert von Siro (02.11.2018 um 06:19 Uhr)
Hatte mich vertippt
Ntl
... t+=x
cnt ist bei mir der Multiplikator
PS
Welche Compileroptimierungsstufe hast du?
Offenbar musst den Schleifenzähler wirklich auch global definieren
Geändert von HaWe (02.11.2018 um 06:47 Uhr)
hier benötigt er 34 Zyklen.Code:t=cnt; for(i=0; i<2;i++) cnt+=t;
The current licence does not permit the selected optimization level, using level -O1![]()
Geändert von Siro (02.11.2018 um 06:43 Uhr)
Edit
Stimmt
Hatte mich vertan
cnt war bei mir der Multiplikator
x der Multiplikant
t das Ergebnis
Also anstelle
t=x*cnt
Alternativ:
int i, x, cnt;
t=x;
for( i=1; i<cnt;i++) t+=x;
Geändert von HaWe (02.11.2018 um 06:57 Uhr)
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 21:38 Uhr)
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 14:07 Uhr)
Lesezeichen