Things should be made as simple as possible, but not any simpler.
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
Fixed-point berekeningen 5.75 4.4 Q4 Precisie: 1/16 =0.0625
Fixed-point berekeningen Optellen:
Fixed-point berekeningen Aftellen: 1011 (11) - 0011 (3) 001011 (11) + 111101 (-3) 1001000 (8)
Fixed-point berekeningen Vermenigvuldigen Negatief getal aanvullen met een 1
Fixed-point berekeningen Conversie van float naar fixed point Vermenigvuldig met 2 N en rond af naar dichtstbijzijnde integer. Voorbeeld: N=4 1.75 *2 4 =28 N Het aantalbits achter de komma 0 0 0 1 1 1 0 0 (int)(f * (1<<N) + (F>=0? 0.5 : -0.5))
Fixed-point berekeningen Conversie van fixed point naar float 0 0 0 1 1 1 0 0? Getal delen door 2 N (float)f / (1<<N) 1.75
Fixed-point berekeningen Conversie van int naar fixed point Vermenigvuldigen met 2 N (1<<N)
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;
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;
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.
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; } (gcc) int tel3op(int aantal) { return aantal+3; }
main:.lfb0: Optimalisatie technieken.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 Zonder inline 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
main:.lfb0: Optimalisatie technieken met inline.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
Alternatief voor inline #include <stdio.h> macro #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;
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.
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);
#include <stdio.h> int processnodea(void); int processnodeb(void); int processnodec(void); intmain() { 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; }
int main { int (* nodefuncties[])( ) = {processnodea, processnodeb, processnodec}; status = nodefuncties[getnodetype()]( ); }
For loop Aftellen is voordeliger dan optellen
For loop Aftellen is voordeliger dan optellen Extra vergelijking
Limiteer het gebruik van C++ Gebruik van templates, exceptions, runtime type information hebben hoge kosten.