Hallo Forum,
Mir ist beim schreiben einer Library ein mögliches Optimierungsproblem
aufgefallen:
Testcode:
1 | typedef unsigned char uint8_t;
|
2 |
|
3 | extern uint8_t (*fp)(uint8_t);
|
4 |
|
5 | void foo(uint8_t (*param1)(uint8_t)) {
|
6 | fp = param1;
|
7 | }
|
8 | void bar(void) {
|
9 | fp(0xFF);
|
10 | fp(0xFF);
|
11 | }
|
kompiliert mit avr-gcc -S -Os -Wall -mmcu=avr6 test_fp.c zu
1 | foo:
|
2 | sts fp+1,r25
|
3 | sts fp,r24
|
4 | ret
|
5 |
|
6 | bar:
|
7 | lds r30,fp
|
8 | lds r31,fp+1
|
9 | ldi r24,lo8(-1)
|
10 | eicall
|
11 | lds r30,fp
|
12 | lds r31,fp+1
|
13 | ldi r24,lo8(-1)
|
14 | eijmp
|
15 |
|
16 | .ident "GCC: (GNU) 5.3.1 20160106"
|
Man sieht: die Adresse der Funktion wird 2 mal, bzw. vor jedem
Funktionsaufruf neu geladen. Wenn man jetzt (so wie ich) häufig diese
indirekten Funktionsaufrufe benutzt, geht das sowohl zulasten der
Laufzeit als auch zulasten des Speichers.
Jetzt meine Frage:
Ist das eine Optimierungsproblem, oder kann/muss ich den Compiler
irgendwie dazu überreden, die Adresse in den Registern zu halten?
Wie man im erzeugten asm-Code sehen kann, ist mein avr-gcc die Version
5.3.1 aus dem trunk vom 06.01.2016, also nicht der neuste.
Ich habe leider im Moment keinen anderen Compiler auf der Festplatte,
deshalb kann ich da nichts vergleichen.
Kann jemand, der eine qualifiziertere Meinung hat als ich mal etwas dazu
sagen?
Mit freundlichen Grüßen und frohe Weihnachten,
N.G.