Optimalisatie technieken
Optimalisatie technieken
Things should be made as simple as possible, but not any simpler.
Optimalisatie technieken Floatingpoint berekeningen Floatingpoint getallen kun je praktisch niet met elkaar vergelijken.
●
De meeste embedded systemen hebben geen floatingpoint processor => floatingpoint berekeningen kosten veel tijd.
●
Fixed-point berekeningen Voorbeeld fixed point Notatie ●M.N 4.4 ●QN Q4 M is aantal integer bits, N is de fractionele bits
Optimalisatie technieken Fixed-point berekeningen 4.4 Q4
5.75 Precisie: 1/16 =0.0625
Optimalisatie technieken Fixed-point berekeningen Optellen:
Optimalisatie technieken Fixed-point berekeningen Aftellen:
-
1011 (11) 0011 (3)
001011 (11) + 111101 (-3) 1001000 (8)
Optimalisatie technieken Fixed-point berekeningen Vermenigvuldigen
Negatief getal aanvullen met een 1
Optimalisatie technieken N Fixed-point berekeningen
Het aantal bits achter de komma
Conversie van float naar fixed point N en rond af naar Vermenigvuldig met 2 dichtstbijzijnde integer.
●
Voorbeeld: N=4 4
1.75 *2 0
0
0
1
1
=28 1
0
0
(int)(F * (1<
=0 ? 0.5 : -0.5))
Optimalisatie technieken Fixed-point berekeningen
Conversie van fixed point naar float
●
0
0
0
1
1
?
1
0
1.75
0
Getal delen door 2N (float)F / (1<
Optimalisatie technieken Fixed-point berekeningen
Conversie van int naar fixed point
●
Vermenigvuldigen met 2N (1<
Optimalisatie technieken Fixed-point berekeningen
16.16
int main() { #define PI 3.1415926535 int a=(int)(PI* (1<<16) + (PI>=0 ? 0.5 : -0.5)); int b=(int)(PI* (1<<16) + (PI>=0 ? 0.5 : -0.5)); int c,d; c=a+a; d= a*a; d=(a*a)>>16; d=((long)a*a)>>16;
a*a=18 722 179 851
float fa=(float)c/(1<<16); float fb=(float)d/(1<<16); printf("fa=%f fb=%f\n",fa,fb); return 0; }
Optimalisatie technieken Fixed-point arithmetic int main() { #define A 2.0 #define B 1.0 int a=(int)(A* (1<<16) + (A>=0 ? 0.5 : -0.5)); int b=(int)(B* (1<<16) + (B>=0 ? 0.5 : -0.5)); int d=a/b; int d=((long)a<<16)/b;
float fd=(float)d/(1<<16); printf("fd=%f ",d); return 0; }
Optimalisatie technieken Vermijd standaard bibliotheek functies •
Standaard bibliotheek functies zijn grote en langzame functies o De strupr functie lijkt kort maar roept o.a. de functies
strlower, strcmp, strcpy aan. o De functie printf, sprintf gebruikt o.a. floatingpoint
bewerkingen. Vaak zijn er speciale functies zoals iprintf.
Optimalisatie technieken Inline functies Door een functie inline te declareren wordt er niet gesprongen naar de functie maar wordt de functie direct in de code verwerkt. int tel3op(int); inline int tel3op(int aantal) __attribute__((always_inline)); int main() { int a,b; a=tel3op(7); b=tel3op(8); return 0; } int tel3op(int aantal) { return aantal+3; }
(gcc)
Optimalisatie technieken Zonder inline main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $16, %rsp movl $7, %edi call tel3op movl %eax, -8(%rbp) movl $8, %edi call tel3op movl %eax, -4(%rbp) movl $0, %eax leave .cfi_def_cfa 7, 8 ret .cfi_endproc
tel3op: .LFB1: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl %edi, -4(%rbp) movl -4(%rbp), %eax addl $3, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc
Optimalisatie technieken met inline main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $7, -8(%rbp) movl -8(%rbp), %eax addl $3, %eax movl %eax, -16(%rbp) movl $8, -4(%rbp) movl -4(%rbp), %eax addl $3, %eax movl %eax, -12(%rbp) movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc
tel3op: .LFB1: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl %edi, -4(%rbp) movl -4(%rbp), %eax addl $3, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc
Optimalisatie technieken Alternatief voor inline macro #include <stdio.h> #define min(x,y) ((x) <(y)) ? (x):(y) int main() { int a=4,b=5,m; m=min(b,a); printf("het minimunum van a en b=%d\n",m); return 0; }
Optimalisatie technieken Table lookups enum NodeType {NODE_A, NODE_B, NODE_C}; switch (getNodeType( )) { case NODE_A: . . case NODE_B: . . case NODE_C: . . }
Zet de node die het meest wordt aangeroepen bovenaan. ●Indien de nodes opeenvolgend zijn, maak een array van functiepointer . ●
Optimalisatie technieken enum NodeType {NODE_A, NODE_B, NODE_C}; Array van functiepointers
De aan te roepen functies. int processNodeA(void); int processNodeB(void); int processNodeC(void);
Declaratie array. int (*nodeFuncties[3]) (void);
Optimalisatie technieken #include <stdio.h> int processNodeA(void); int processNodeB(void); int processNodeC(void); int main() { int (*nodeFuncties[3]) (void); nodeFuncties[0]=processNodeA; nodeFuncties[1]=processNodeB; nodeFuncties[2]=processNodeC; int status=nodeFuncties[0](); printf("%d \n",status); }
int processNodeA(void) { puts("NodeA"); return 0; } int processNodeB(void) { puts("NodeB"); return 1; } int processNodeC(void) { puts("Node"); return 2; }
Optimalisatie technieken int main { int (* nodeFuncties[])( ) = {processNodeA, processNodeB, processNodeC}; status = nodeFuncties[getNodeType()]( );
}
Optimalisatie technieken For loop Aftellen is voordeliger dan optellen
Optimalisatie technieken For loop Aftellen is voordeliger dan optellen
Extra vergelijking
Optimalisatie technieken
Limiteer het gebruik van C++ Gebruik van templates, exceptions, runtime type information hebben hoge kosten.