Programowanie mikroprocesorów jednoukładowych Optymalizacja programów w asemblerze Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 1 / 21
Plan I Optymalizacja Pisanie w ASM Jak rozpocząć optymalizację Kolejkowanie instrukcji Budowa procedury w ASM Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 2 / 21
Program w C I 1 #i n c l u d e <s t d i o. h> 2 i n t s q u a r e ( i n t i ) ; 3 i n t main ( v o i d ) 4 { 5 i n t i ; 6 f o r ( i =0; i <10; i ++) 7 { 8 p r i n t f ( " Square 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 r e t u r n i i ; 14 } Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 3 / 21
Procedura w ASM I 1 s q u a r e 2 AREA. t e x t, CODE, READONLY 3 EXPORT s q u a r e 4 ; i n t s q u a r e ( i n t i ) 5 MUL r1, r0, r0 ; r1 = r0 r0 6 MOV r0, r1 ; r0 = r1 7 MOV pc, l r ; r e t u r n r0 8 END Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 4 / 21
Wersja dla ARMv4T I 1 AREA. t e x t, CODE, READONLY 2 EXPORT s q u a r e 3 ; i n t s q u a r e ( i n t i ) 4 s q u a r e 5 MUL r1, r0, r0 ; r1 = r0 r0 6 MOV r0, r1 ; r0 = r1 7 BX l r ; r e t u r n r0 8 END Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 5 / 21
Wywoływanie instrukcji z poziomu ASM I 1 AREA. t e x t, CODE, READONLY 2 EXPORT main 3 IMPORT L i b $ $ R e q u e s t $ $ a r m l i b, WEAK 4 IMPORT main ; C l i b r a r y e n t r y 5 IMPORT p r i n t f ; p r i n t s to s t d o u t 6 irn4 7 ; i n t main ( v o i d ) 8 main 9 STMFD sp!, { i, l r } 10 MOV i, #0 11 l o o p 12 ADR r0, p r i n t _ s t r i n g 13 MOV r1, i 14 MUL r2, i, i 15 BL p r i n t f Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 6 / 21
Wywoływanie instrukcji z poziomu ASM II 16 ADD i, i, #1 17 CMP i, #10 18 BLT l o o p 19 LDMFD sp!, { i, pc } 20 p r i n t _ s t r i n g 21 DCB " Square o f %d i s %d\n", 0 22 END Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 7 / 21
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 the number o f v a l u e s to 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 11 września 2017 8 / 21
Przekazywanie dużej ilości argumentów I 1 AREA. t e x t, CODE, READONLY 2 EXPORT sumof 3 N RN 0 ; number o f e l e m e n t s to sum 4 sum RN 1 ; c u r r e n t sum 5 ; i n t sumof ( i n t N,... ) 6 sumof 7 SUBS N, N, #1 ; do we have one element 8 MOVLT sum, #0 ; no e l e m e n t s to sum! 9 SUBS N, N, #1 ; do we have two e l e m e n t s 10 ADDGE sum, sum, r 2 11 SUBS N, N, #1 ; do we have t h r e e e l e m e n t s 12 ADDGE sum, sum, r 3 13 MOV r2, sp ; top o f s t a c k 14 l o o p 15 SUBS N, N, #1 ; do we have a n o t h e r element Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 9 / 21
Przekazywanie dużej ilości argumentów II 16 LDMGEFD r2!, { r3 } ; l o a d from the s t a c k 17 ADDGE sum, sum, r 3 18 BGE l o o p 19 MOV r0, sum 20 MOV pc, l r ; r e t u r n r0 21 END Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 10 / 21
Jak rozpocząć optymalizację profiler - pomiar czasu potrzebnego na wykonanie danej funkcji 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 11 września 2017 11 / 21
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: 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. Instrukcje wczytywania, które wczytują N 32-bitowych 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 pojedynczej wartości, która zajmuje dwa cykle. Jeżeli instrukcja wczytuje do pc, wtedy należy dodać dwa cykle. 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. instrukcje skoków to trzy cykle instrukcje zapisu, które zapisują mnożenie przyjmuje różne wartości cykli w zależności od podanych parametrów Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 12 / 21
Kolejkowanie instrukcji wczytywania I 1 v o i d s t r _ t o l o w e r ( char out, char i n ) 2 { 3 u n s i g n e d i n t c ; 4 do 5 { 6 c = ( i n ++); 7 i f ( c>= A && c<= Z ) 8 { 9 c=c+( a A ) ; 10 } 11 ( out++) = ( char ) c ; 12 } w h i l e ( c ) ; 13 } Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 13 / 21
Kolejkowanie instrukcji wczytywania ASM I 1 s t r _ t o l o w e r 2 LDRB r2, [ r1 ],#1 ; c = ( i n++) 3 SUB r3, r2,#0 x41 ; r3 = c A 4 CMP r3,#0 x19 ; i f ( c <= Z A ) 5 ADDLS r2, r2,#0 x20 ; c += a A 6 STRB r2, [ r0 ],#1 ; ( out++) = ( char ) c 7 CMP r2,#0 ; i f ( c!=0) 8 BNE s t r _ t o l o w e r ; goto s t r _ t o l o w e r 9 MOV pc, r14 ; r e t u r n Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 14 / 21
Kolejkowanie instrukcji wczytywania ASM I 1 out RN 0 ; p o i n t e r to output s t r i n g 2 i n RN 1 ; p o i n t e r to i n p u t s t r i n g 3 c RN 2 ; c h a r a c t e r l o a d e d 4 t RN 3 ; s c r a t c h r e g i s t e r 5 ; v o i d s t r _ t o l o w e r _ p r e l o a d ( char out, char i n ) 6 s t r _ t o l o w e r _ p r e l o a d 7 LDRB c, [ i n ], #1 ; c = ( i n++) 8 l o o p 9 SUB t, c, # A ; t = c A 10 CMP t, # Z A ; i f ( t <= Z A ) 11 ADDLS c, c, # a A ; c += a A ; 12 STRB c, [ out ], #1 ; ( out++) = ( char ) c ; 13 TEQ c, #0 ; t e s t i f c==0 14 LDRNEB c, [ i n ], #1 ; i f ( c!=0) { c= i n ++; 15 BNE l o o p ; goto l o o p ; } Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 15 / 21
Kolejkowanie instrukcji wczytywania ASM II 16 MOV pc, l r ; r e t u r n Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 16 / 21
Kolejkowanie instrukcji wczytywania ASM I 1 out RN 0 ; p o i n t e r to output s t r i n g 2 i n RN 1 ; p o i n t e r to i n p u t s t r i n g 3 ca0 RN 2 ; c h a r a c t e r 0 4 t RN 3 ; s c r a t c h r e g i s t e r 5 ca1 RN 12 ; c h a r a c t e r 1 6 ca2 RN 14 ; c h a r a c t e r 2 7 ; v o i d s t r _ t o l o w e r _ u n r o l l e d ( char out, char i n ) 8 s t r _ t o l o w e r _ u n r o l l e d 9 STMFD sp!, { l r } ; f u n c t i o n e n t r y 10 loop_next3 11 LDRB ca0, [ i n ], #1 ; ca0 = i n ++; 12 LDRB ca1, [ i n ], #1 ; ca1 = i n ++; 13 LDRB ca2, [ i n ], #1 ; ca2 = i n ++; 14 SUB t, ca0, # A ; c o n v e r t ca0 to l o w e r c a s e 15 CMP t, # Z A Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 17 / 21
Kolejkowanie instrukcji wczytywania ASM II 16 ADDLS ca0, ca0, # a A 17 SUB t, ca1, # A ; c o n v e r t ca1 to l o w e r c a s e 18 CMP t, # Z A 19 ADDLS ca1, ca1, # a A 20 SUB t, ca2, # A ; c o n v e r t ca2 to l o w e r c a s e 21 CMP t, # Z A 22 ADDLS ca2, ca2, # a A 23 STRB ca0, [ out ], #1 ; out++ = ca0 ; 24 TEQ ca0, #0 ; i f ( ca0!=0) 25 STRNEB ca1, [ out ], #1 ; out++ = ca1 ; 26 TEQNE ca1, #0 ; i f ( ca0!=0 && ca1!=0) 27 STRNEB ca2, [ out ], #1 ; out++ = ca2 ; 28 TEQNE ca2, #0 ; i f ( ca0!=0 && ca1!=0 && ca2!=0) 29 BNE loop_next3 ; goto loop_next3 ; 30 LDMFD sp!, { pc } ; r e t u r n ; Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 18 / 21
Budowa procedury w ASM I 1 routine_name 2 STMFD sp!, { r4 r12, l r } ; s t a c k saved r e g i s t e r s 3 ; body o f r o u t i n e 4 ; the f o u r t e e n r e g i s t e r s r0 r12 and l r a r e a v a i l a b l e 5 LDMFD sp!, { 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 11 września 2017 19 / 21
Budowa procedury w ASM I 1 routine_name 2 STMFD sp!, { r4 r12, l r } ; s t a c k saved r e g i s t e r s 3 ; body o f r o u t i n e 4 ; r e g i s t e r s r0 r12 and l r a v a i l a b l e 5 LDMFD sp!, { r4 r12, l r } ; r e s t o r e r e g i s t e r s 6 BX l r ; r e t u r n, with mode s w i t c h Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 20 / 21
References Andrew Sloss, Dominic Symes, and Chris Wright. ARM System Developer s Guide: Designing and Optimizing System Software. Morgan Kaufmann Publishers Inc., San Francisco, CA, USA, 2004. Mariusz Naumowicz Programowanie mikroprocesorów jednoukładowych 11 września 2017 21 / 21