Optymalizacja programów
Transkrypt
Optymalizacja programów
Programowanie mikroprocesorów
jednoukładowych
Optymalizacja programów w asemblerze
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
1 / 20
Plan I
Optymalizacja
Pisanie w ASM
Jak rozpocząć optymalizację
Kolejkowanie instrukcji
Budowa procedury w ASM
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
2 / 20
Program w C I
1 #i n c l u d e < s t d i o . h>
2 i n t square ( i n t i ) ;
3 i n t main ( v o i d )
4 {
5
int i ;
6
f o r ( i =0; i <10; i ++)
7
{
8
p r i n t f ( " S q u a r e o f %d i s %d\n " , i , s q u a r e ( i ) ) ;
9
}
10 }
11 i n t s q u a r e ( i n t i )
12 {
13
return i ∗ i ;
14 }
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
3 / 20
Procedura w ASM I
1
2
3
4
5
6
7
8
square
AREA | . t e x t | , CODE, READONLY
EXPORT s q u a r e
; i n t square ( i n t i )
MUL r1 , r0 , r 0 ; r 1 = r 0 ∗ r 0
MOV r0 , r 1 ; r 0 = r 1
MOV pc , l r ; r e t u r n r 0
END
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
4 / 20
Wersja dla ARMv4T I
1
2
3
4
5
6
7
8
AREA | . t e x t | , CODE, READONLY
EXPORT s q u a r e
; i n t square ( i n t i )
square
MUL r1 , r0 , r 0 ; r 1 = r 0 ∗ r 0
MOV r0 , r 1 ; r 0 = r 1
BX l r ; r e t u r n r 0
END
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
5 / 20
Wywoływanie instrukcji z poziomu ASM I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
AREA | . t e x t | , CODE, READONLY
EXPORT main
IMPORT | L i b $ $ R e q u e s t $ $ a r m l i b | , WEAK
IMPORT __main ; C l i b r a r y e n t r y
IMPORT p r i n t f ; p r i n t s t o s t d o u t
iRN4
; i n t main ( v o i d )
main
STMFD s p ! , { i , l r }
MOV i , #0
loop
ADR r0 , p r i n t _ s t r i n g
MOV r1 , i
MUL r2 , i , i
BL p r i n t f
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
6 / 20
Wywoływanie instrukcji z poziomu ASM II
16
17
18
19
20
21
22
ADD i , i , #1
CMP i , #10
BLT l o o p
LDMFD s p ! , { i , pc }
print_string
DCB " S q u a r e o f %d i s %d\n " , 0
END
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
7 / 20
Przekazywanie dużej ilości argumentów I
1 #i n c l u d e < s t d i o . h>
2 /∗ N i s t h e number o f v a l u e s t o sum i n l i s t . . . ∗/
3 i n t sumof ( i n t N, . . . ) ;
4 i n t main ( v o i d )
5 {
6
p r i n t f ( " Empty sum=%d\n " , sumof ( 0 ) ) ;
7
p r i n t f ("1=%d\n " , sumof ( 1 , 1 ) ) ;
8
p r i n t f ("1+2=%d\n " , sumof ( 2 , 1 , 2 ) ) ;
9
p r i n t f ("1+2+3=%d\n " , sumof ( 3 , 1 , 2 , 3 ) ) ;
10
p r i n t f ("1+2+3+4=%d\n " , sumof ( 4 , 1 , 2 , 3 , 4 ) ) ;
11
p r i n t f ("1+2+3+4+5=%d\n " , sumof ( 5 , 1 , 2 , 3 , 4 , 5 ) ) ;
12
p r i n t f ("1+2+3+4+5+6=%d\n " , sumof ( 6 , 1 , 2 , 3 , 4 , 5 , 6 ) ) ;
13 }
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
8 / 20
Przekazywanie dużej ilości argumentów I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
AREA | . t e x t | , CODE, READONLY
EXPORT sumof
N RN 0 ; number o f e l e m e n t s t o sum
sum RN 1 ; c u r r e n t sum
; i n t sumof ( i n t N, . . . )
sumof
SUBS N, N, #1 ; do we h av e one e l e m e n t
MOVLT sum , #0 ; no e l e m e n t s t o sum !
SUBS N, N, #1 ; do we h av e two e l e m e n t s
ADDGE sum , sum , r 2
SUBS N, N, #1 ; do we h av e t h r e e e l e m e n t s
ADDGE sum , sum , r 3
MOV r2 , s p ; t o p o f s t a c k
loop
SUBS N, N, #1 ; do we h av e a n o t h e r e l e m e n t
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
9 / 20
Przekazywanie dużej ilości argumentów II
16
17
18
19
20
21
LDMGEFD r 2 ! , { r 3 } ; l o a d from t h e s t a c k
ADDGE sum , sum , r 3
BGE l o o p
MOV r0 , sum
MOV pc , l r ; r e t u r n r 0
END
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
10 / 20
Jak rozpocząć optymalizację
I
profiler - pomiar czasu potrzebnego na wykonanie danej funkcji
I
cycle counting - zliczanie cykli zegara potrzebnych na wykonanie funkcji i porównywanie
ich przed optymalizacją i po optymalizacji
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
11 / 20
Kolejkowanie instrukcji
Zakładając że instrukcja warunkowa w ARM potrzebuje jedno cyklu gdy warunek jest
niespełniony. Jeżeli warunek jest spełniony to:
I ALU dla dodawania, odejmowania oraz logicznych operacji potrzebuje jednego cyklu.
Tyczy się to także dla przesuwania jeżeli jest to bezpośrednie przesuwanie, przy użyciu
rejestry należy doliczyć jeden cykl, a przy zapisie do pc dwa cykle.
I Instukcje wczytywania, które wszytują N 32-biotwych słów z pamięci np. LDR i LDM
wymagają N cykli, ale w rezultacie nie otrzymujemy ostatniego wyrazi zgdnie z cyklami
zegara związane jest to z czytaniem adresu. WYjątkiem jest LDM dla pojedycznej wartości,
która zajmuje dwa cykle. Jeżeli instrukcja wczytuje do pc, wtedy należy dodać dwa cykle.
I instrukcje wczytywania, które wczytują 16-bitowe lub 8-bitowe dane jak np. LDRB,
LDRSB, LDRH u LDRSH zajmuję jeden cykl. Rezultat nie jest dostępny po dwóch
cyklach, podobnie jak powyżej.
I instrukcje skoków to trzy cykle
I instrukcje zapisu, które zapisują
I mnożenie przyjmuje różne wartości cykli w zależności od podanych parametrów
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
12 / 20
Kolejkowanie instrukcji wczytywania I
1
2
3
4
5
6
7
8
9
10
11
12
13
v o i d s t r _ t o l o w e r ( c h a r ∗ out , c h a r ∗ i n )
{
unsigned i n t c ;
do
{
c = ∗ ( i n ++);
i f ( c>=’A ’ && c<=’Z ’ )
{
c=c +( ’ a ’ −’A ’ ) ;
}
∗ ( o u t++) = ( c h a r ) c ;
} while (c );
}
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
13 / 20
Kolejkowanie instrukcji wczytywania ASM I
1
2
3
4
5
6
7
8
9
str_tolower
LDRB r2 , [ r 1 ] ,#1 ; c = ∗ ( i n ++)
SUB r3 , r2 ,#0 x41 ; r 3 = c −’A ’
CMP r3 ,#0 x19 ; i f ( c <=’Z’ − ’A ’ )
ADDLS r2 , r2 ,#0 x20 ; c +=’a ’ − ’A ’
STRB r2 , [ r 0 ] ,#1 ; ∗ ( o u t++) = ( c h a r ) c
CMP r2 ,#0 ; i f ( c !=0)
BNE s t r _ t o l o w e r ; g o t o s t r _ t o l o w e r
MOV pc , r 1 4 ; r e t u r n
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
14 / 20
Kolejkowanie instrukcji wczytywania ASM I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
o u t RN 0 ; p o i n t e r t o o u t p u t s t r i n g
i n RN 1 ; p o i n t e r t o i n p u t s t r i n g
c RN 2 ; c h a r a c t e r l o a d e d
t RN 3 ; s c r a t c h r e g i s t e r
; v o i d s t r _ t o l o w e r _ p r e l o a d ( c h a r ∗ out , c h a r ∗ i n )
str_tolower_preload
LDRB c , [ i n ] , #1 ; c = ∗ ( i n ++)
loop
SUB t , c , #’A ’ ; t = c −’A ’
CMP t , #’Z’ − ’A ’ ; i f ( t <= ’ Z’ − ’A ’ )
ADDLS c , c , #’a ’ − ’A ’ ; c += ’ a ’ − ’A ’ ;
STRB c , [ o u t ] , #1 ; ∗ ( o u t++) = ( c h a r ) c ;
TEQ c , #0 ; t e s t i f c==0
LDRNEB c , [ i n ] , #1 ; i f ( c !=0) { c=∗ i n ++;
BNE l o o p ; g o t o l o o p ; }
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
15 / 20
Kolejkowanie instrukcji wczytywania ASM II
16 MOV pc , l r ; r e t u r n
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
16 / 20
Kolejkowanie instrukcji wczytywania ASM I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
o u t RN 0 ; p o i n t e r t o o u t p u t s t r i n g
i n RN 1 ; p o i n t e r t o i n p u t s t r i n g
ca0 RN 2 ; c h a r a c t e r 0
t RN 3 ; s c r a t c h r e g i s t e r
ca1 RN 12 ; c h a r a c t e r 1
ca2 RN 14 ; c h a r a c t e r 2
; v o i d s t r _ t o l o w e r _ u n r o l l e d ( c h a r ∗ out , c h a r ∗ i n )
str_tolower_unrolled
STMFD s p ! , { l r } ; f u n c t i o n e n t r y
loop_next3
LDRB ca0 , [ i n ] , #1 ; ca0 = ∗ i n ++;
LDRB ca1 , [ i n ] , #1 ; ca1 = ∗ i n ++;
LDRB ca2 , [ i n ] , #1 ; ca2 = ∗ i n ++;
SUB t , ca0 , #’A ’ ; c o n v e r t ca0 t o l o w e r c a s e
CMP t , #’Z’ − ’A ’
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
17 / 20
Kolejkowanie instrukcji wczytywania ASM II
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
ADDLS ca0 , ca0 , #’a ’ − ’A ’
SUB t , ca1 , #’A ’ ; c o n v e r t ca1 t o l o w e r c a s e
CMP t , #’Z’ − ’A ’
ADDLS ca1 , ca1 , #’a ’ − ’A ’
SUB t , ca2 , #’A ’ ; c o n v e r t ca2 t o l o w e r c a s e
CMP t , #’Z’ − ’A ’
ADDLS ca2 , ca2 , #’a ’ − ’A ’
STRB ca0 , [ o u t ] , #1 ; ∗ o u t++ = ca0 ;
TEQ ca0 , #0 ; i f ( ca0 !=0)
STRNEB ca1 , [ o u t ] , #1 ; ∗ o u t++ = ca1 ;
TEQNE ca1 , #0 ; i f ( ca0 !=0 && ca1 !=0)
STRNEB ca2 , [ o u t ] , #1 ; ∗ o u t++ = ca2 ;
TEQNE ca2 , #0 ; i f ( ca0 !=0 && ca1 !=0 && ca2 !=0)
BNE l o o p _ n e x t 3 ; g o t o l o o p _ n e x t 3 ;
LDMFD s p ! , { pc } ; r e t u r n ;
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
18 / 20
Budowa procedury w ASM I
1 routine_name
2 STMFD s p ! , { r4−r12 , l r } ; s t a c k s a v e d r e g i s t e r s
3 ; body o f r o u t i n e
4 ; t h e f o u r t e e n r e g i s t e r s r0−r 1 2 and l r a r e a v a i l a b l e
5 LDMFD s p ! , { r4−r12 , pc } ; r e s t o r e r e g i s t e r s and r e t u r n
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
19 / 20
Budowa procedury w ASM I
1 routine_name
2 STMFD s p ! , { r4−r12 , l r } ;
3 ; body o f r o u t i n e
4 ; r e g i s t e r s r0−r 1 2 and l r
5 LDMFD s p ! , { r4−r12 , l r } ;
6 BX l r ; r e t u r n , w i t h mode
Mariusz Naumowicz
stack saved r e g i s t e r s
available
restore registers
switch
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
20 / 20
References
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
23 listopada 2016
21 / 20