Dis ist abhängig von deinem Compiler und welche Optimierungsstrategien er anwendet, sowie wieviel Wissen über dein Programm du ihm mitgibst...
Um hier guten Code zu machen braucht dein Compiler mindestens folgende Optimierungsstrategien:
Loop unrolling, strength reduction, common subexbression elimination.
Hier mal als Standard-C:
Code:
#define DIMX 2
#define DIMY 2
char array[DIMX][DIMY] =
{
{5, 6},
{3, 4}
};
char foo (char a[DIMX][DIMY])
{
char sum = 0;
unsigned char x, y;
for (x=0; x < DIMX; x++)
for (y=0; y < DIMY; y++)
sum += a[x][y];
return sum;
}
int main()
{
return foo (array);
}
Als Compiler nehme ich einen avr-gcc (C --> AVR-Assembler)
Ich rechne dabei der Einfachheit halber mit 8-Bit Werten, sonst sieht man garnix mehr (AVR ist eine 8-Bit MCU). Angegeben sind die Optimierungsstufen.
-O0
Code:
foo:
/* prologue: frame size=5 */
push r28
push r29
in r28,__SP_L__
in r29,__SP_H__
sbiw r28,5
in __tmp_reg__,__SREG__
cli
out __SP_H__,r29
out __SREG__,__tmp_reg__
out __SP_L__,r28
/* prologue end (size=10) */
std Y+1,r24 ; a, a
std Y+2,r25 ; a, a
std Y+3,__zero_reg__ ; sum,
std Y+4,__zero_reg__ ; x,
.L2:
ldd r24,Y+4 ; x, x
cpi r24,lo8(2) ; x,
brsh .L3 ; ,
std Y+5,__zero_reg__ ; y,
.L5:
ldd r24,Y+5 ; y, y
cpi r24,lo8(2) ; y,
brsh .L4 ; ,
ldd r24,Y+4 ; x, x
mov r18,r24 ; x, x
clr r19 ; x
ldd r24,Y+5 ; y, y
mov r20,r24 ; y, y
clr r21 ; y
movw r24,r18 ; x, x
add r18,r24 ; tmp49, x
adc r19,r25 ; tmp49, x
ldd r24,Y+1 ; a, a
ldd r25,Y+2 ; a, a
add r24,r18 ; tmp50, tmp49
adc r25,r19 ; tmp50, tmp49
movw r30,r24 ; tmp52, tmp50
add r30,r20 ; tmp52, y
adc r31,r21 ; tmp52, y
ldd r25,Y+3 ; sum, sum
ld r24,Z ; tmp54,
add r24,r25 ; tmp55, sum
std Y+3,r24 ; sum, tmp55
ldd r24,Y+5 ; y, y
subi r24,lo8(-(1)) ; tmp57,
std Y+5,r24 ; y, tmp57
rjmp .L5 ;
.L4:
ldd r24,Y+4 ; x, x
subi r24,lo8(-(1)) ; tmp59,
std Y+4,r24 ; x, tmp59
rjmp .L2 ;
.L3:
ldd r24,Y+3 ; sum, sum
clr r25 ; sum
sbrc r24,7 ; sum
com r25 ; sum
/* epilogue: frame size=5 */
adiw r28,5
in __tmp_reg__,__SREG__
cli
out __SP_H__,r29
out __SREG__,__tmp_reg__
out __SP_L__,r28
pop r29
pop r28
ret
/* epilogue end (size=9) */
/* function foo size 62 (43) */
-Os
Code:
foo:
/* prologue: frame size=0 */
/* prologue end (size=0) */
movw r22,r24 ; a, a
ldi r20,lo8(0) ; sum,
ldi r21,lo8(1) ; x,
ldi r18,lo8(0) ; tmp78,
ldi r19,hi8(0) ; tmp78,
.L9:
movw r30,r18 ; tmp55, tmp78
add r30,r22 ; tmp55, a
adc r31,r23 ; tmp55, a
ld r24,Z+ ; tmp65,
add r20,r24 ; sum, tmp65
ld r24,Z ; tmp70,
add r20,r24 ; sum, tmp70
subi r21,lo8(-(-1)) ; x,
subi r18,lo8(-(2)) ; tmp78,
sbci r19,hi8(-(2)) ; tmp78,
sbrs r21,7 ; x,
rjmp .L9 ;
mov r24,r20 ; <result>, sum
clr r25 ; <result>
sbrc r24,7 ; <result>
com r25 ; <result>
/* epilogue: frame size=0 */
ret
/* epilogue end (size=1) */
/* function foo size 22 (21) */
-O2 -funroll-loops
Code:
foo:
/* prologue: frame size=0 */
/* prologue end (size=0) */
movw r30,r24 ; a, a
ld r24,Z ; sum,* a
ldd r25,Z+1 ; tmp71,
add r24,r25 ; sum, tmp71
ldd r25,Z+2 ; tmp66,
add r24,r25 ; sum, tmp66
ldd r25,Z+3 ; tmp71,
add r24,r25 ; sum, tmp71
clr r25 ; <result>
sbrc r24,7 ; <result>
com r25 ; <result>
/* epilogue: frame size=0 */
ret
/* epilogue end (size=1) */
/* function foo size 12 (11) */
Lesezeichen