Hallo Forum, ich habe gerade mit erstaunen festgestellt, dass der GCC konstante Ausdrücke wie tmp = (18.6 * 10) nicht zur compile-time berechnet, sondern die floating point Routinen zur run-time bemüht, was zu einem erheblichen Mehr an Code und Rechenzeit führt. Ich hatte erwartet, dass daraus ein simples tmp = 186 wird. Gibt es eine Möglichkeit den GCC dazu zubringen konstante Ausdrücke zur compile-time zu berechnen? Welchen switch habe ich übersehen? Vielen Dank Bernd
Das tut der GCC mit Sicherheit. Allerdings wird daraus nicht 186, sondern 186.0 (Float), das könnte der Grund für das beobachtete Verhalten sein.
Das sollte sich aber mit tmp = (int)(18.6 * 10) beheben lassen
Bei einer einfachen Zuweisung sollte das der Compiler selbst erkennen, das Problem dürfte eigentlich nur bei Ausdrücken mit Variablen auftreten: x = x * (18.6 * 10);
> ich habe gerade mit erstaunen festgestellt, dass der GCC konstante > Ausdrücke wie tmp = (18.6 * 10) nicht zur compile-time berechnet, > sondern die floating point Routinen zur run-time bemüht, was zu > einem erheblichen Mehr an Code und Rechenzeit führt. Kannst du mal den exakten Code zeigen? Bei mir: $ cat constant.c int main() { volatile float tmp = (18.6 * 10); } $ avr-gcc constant.c -S -o- -mmcu=atmega48 .file "constant.c" .arch atmega48 _SREG_ = 0x3f _SP_H_ = 0x3e _SP_L_ = 0x3d _tmp_reg_ = 0 _zero_reg_ = 1 .global __do_copy_data .global __do_clear_bss .text .global main .type main, @function main: /* prologue: frame size=4 */ ldi r28,lo8(__stack - 4) ldi r29,hi8(__stack - 4) out _SP_H_,r29 out _SP_L_,r28 /* prologue end (size=4) */ ldi r24,lo8(0x433a0000) ldi r25,hi8(0x433a0000) ldi r26,hlo8(0x433a0000) ldi r27,hhi8(0x433a0000) std Y+1,r24 std Y+2,r25 std Y+3,r26 std Y+4,r27 /* epilogue: frame size=4 */ rjmp exit /* epilogue end (size=1) */ /* function main size 13 (8) */ .size main, .-main /* File "constant.c": code 13 = 0x000d ( 8), prologues 4, epilogues 1 */ Wie man unschwer erkennen kann, wird die Berechnung im Compiler durchgeführt.
Vielen Dank für die Hinweise, habe die Problematik erkannt.
Die entscheidenden Hinweise kamen von Nico und Andreas.
Das Problem ist die Verwendung von Float multipliziert mit einer
integer Variablen. Die Multiplikation mit der Variablen hatte ich in
meinem Text nicht erwähnt, weil ich das nicht für das Problem hielt,
sorry (war auch schon ziemlich spät für mich).
Somit kann ich folgendes Ergenis präsentieren:
es sei
volatile int tmp, x;
Multiplikation int Variable mit int Konstante:
tmp = x * (185);
180: 10 91 38 01 lds r17, 0x0138
184: 89 eb ldi r24, 0xB9 ; 185
186: 18 9f mul r17, r24
188: c0 01 movw r24, r0
18a: 11 24 eor r1, r1
18c: 9a 83 std Y+2, r25 ; 0x02
18e: 89 83 std Y+1, r24 ; 0x01
Multiplikation int Variable mit float Konstante:
tmp = x * (18.6*10);
190: 81 2f mov r24, r17
192: 99 27 eor r25, r25
194: aa 27 eor r26, r26
196: 97 fd sbrc r25, 7
198: a0 95 com r26
19a: ba 2f mov r27, r26
19c: bc 01 movw r22, r24
19e: cd 01 movw r24, r26
1a0: c8 d3 rcall .+1936 ; 0x932 <__floatsisf>
1a2: dc 01 movw r26, r24
1a4: cb 01 movw r24, r22
1a6: 20 e0 ldi r18, 0x00 ; 0
1a8: 30 e0 ldi r19, 0x00 ; 0
1aa: 4a e3 ldi r20, 0x3A ; 58
1ac: 53 e4 ldi r21, 0x43 ; 67
1ae: bc 01 movw r22, r24
1b0: cd 01 movw r24, r26
1b2: 17 d4 rcall .+2094 ; 0x9e2 <__mulsf3>
1b4: dc 01 movw r26, r24
1b6: cb 01 movw r24, r22
1b8: bc 01 movw r22, r24
1ba: cd 01 movw r24, r26
1bc: 9d d3 rcall .+1850 ; 0x8f8 <__fixsfsi>
1be: dc 01 movw r26, r24
1c0: cb 01 movw r24, r22
1c2: 9a 83 std Y+2, r25 ; 0x02
1c4: 89 83 std Y+1, r24 ; 0x01
Multiplikation int Variable mit float Konstante und typecast:
tmp = x * (unsigned int)(18.7*10);
1c6: 8b eb ldi r24, 0xBB ; 187
1c8: 18 9f mul r17, r24
1ca: c0 01 movw r24, r0
1cc: 11 24 eor r1, r1
1ce: 9a 83 std Y+2, r25 ; 0x02
1d0: 89 83 std Y+1, r24 ; 0x01
Das letztere sieht doch schon viel freundlicher aus.
Vielen Dank für die Hilfe.
Gruss Bernd
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.