PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : for then -> Assembler



FuRanKu
15.09.2006, 20:44
Hallo Zusammen,

leider kenne ich mich nicht mit Assembler aus, hätte jedoch eine Frage dazu.
-Wenn ich eine For Then Schleife mache die in Assembler umcompiliert wird, ist es dann schneller, wenn ich die Schritte alle einzeln aufschreibe oder macht der Compiler das sowieso?

Also anstatt:
Ar = Array ((5,6)(3,4));

For i=0; i<2; i++ Then
For j=0; i<2; j++ Then
X= X+Ar[i][j];
Next
Next


So:
X=X+5;
X=X+6;
X=X+3;
X=X+4;

Das ist jetzt natürlich verkleinerter Code ;) So exemplarisch, die eigentliche Matrix ist 9 oder 25fach. Ich frage mich nämlich, ob der Schreibaufwand gerechtfertigt wäre.

-Wieviel Assemblerschritte würde ich in etwa sparen?

Ciao FuRanKu

SprinterSB
17.09.2006, 00:44
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:

#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
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
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
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) */

FuRanKu
24.09.2006, 10:28
Danke für die Antwort.

Wie mein Compiler arbeitet weiss ich leider nicht.
Ist auch nicht für Mikrocontroller, sondern ein Grafikkartenshader. :-b Wußte allerdings nicht wo ich sonst Assemblerprofis finde.

Ich denke ich werde mir die Mühe machen, das alles in Einzelschritte umzuschreiben, denn das erste Beispiel scheint ja einen ziemlichen Overhead zu haben.

Ciao FuRanKu