claudio Postat Aprilie 7, 2011 Partajează Postat Aprilie 7, 2011 Salut, As avea nevoie de niste sfaturi privind optimizarea unui cod. Mai jos sunt cele trei tipuri prin care pot face programul. Care ar fi solutia cea mai buna? (luand in considerare viteza de functionare; usurinta in programare/modificare pe viitor; sau ... alte cerinte; dimensiunea hex-ului - aici este evident ca primul exemplu ar fi optim). #include <avr/io.h>uint8_t a;uint8_t b;uint8_t rez;void fct1() { rez = a + b;}void fct2(){ rez = b + a;}void fct3(){ rez = a - b;}void fct4(){ rez = b - a;}int main(){ fct1(); fct2(); fct3(); fct4();}Compilat are 212byte program si 3bytes data #include <avr/io.h>uint8_t a;uint8_t b;uint8_t rez;uint8_t a2b;void fct12(){ if(a2b) rez = a + b; else rez = b + a;}void fct34(){ if(a2b) rez = a - b; else rez = b - a;}int main(){ a2b=0; fct12(); a2b=1; fct12(); a2b=0; fct34(); a2b=1; fct34();}Compilat are 236byte program si 4bytes data #include <avr/io.h>uint8_t a;uint8_t b;uint8_t rez;uint8_t a2b;uint8_t operatie;void fct1234(){ if(operatie) { if(a2b) rez = a + b; else rez = b + a; } else { if(a2b) rez = a - b; else rez = b - a; }}int main(){ a2b=0; operatie=0; fct1234(); a2b=0; operatie=1; fct1234(); a2b=1; operatie=0; fct1234(); a2b=1; operatie=1; fct1234();}Compilat are 248byte program si 5bytes data Link spre comentariu
Laci Postat Aprilie 7, 2011 Partajează Postat Aprilie 7, 2011 Salut,Nici unul dintre variantele prezentate de tine :)Eu asi face asa:#define OP_ADUNARE '+'#define OP_SCADERE '-'int functie_aritmetica(char op1, char op2, char op_type){int ret_val; switch(op_type) { case OP_ADUNARE: ret_val = op1+op2; break; case OP_ADUNARE: ret_val = op1-op2; break; }//switch(op_type) }//int functie_aritmetica(char op1, char op2, char op_type)void main(){ functie_aritmetica(var1, var2, OP_ADUNARE);} Link spre comentariu
picolo Postat Aprilie 7, 2011 Partajează Postat Aprilie 7, 2011 Acest forum nu are si o sectiune umoristica bine definita, asa ca ma intreb si eu tot aici:Faci optimizare, dar stii ce faci? Link spre comentariu
nana Postat Aprilie 8, 2011 Partajează Postat Aprilie 8, 2011 Optimizarea codului e aia care iti functioneaza cel mai bine si ocupa cel mai putin spatiu. Acum te inteleg daca ai memorie de 1k sa faci optimizari la adunari si scaderi. Cel mai bine optimizat este primul exemplu; Insa func2 b+a nu isi are sensul, pentru ca undeva prin clasa a 1 sau a 2 ai invatzat o proprietate a adunari numita comutativitatea termenilor. deci a+b=b+a, insa nu se poate spune acelasi lucru si despre scadere! deci eu am obtinut si mai bine in felul urmator; #include <avr/io.h>uint8_t a;uint8_t b;uint8_t func1() {return a+b;}uint8_t func2() {return a-b;}uint8_t func3() {return b-a;}// uint8_t func4()// {return b+a;}void main(){func1();func2();func3();//func4();} am obtinut 128 byti program si 2 byti date iar in felul facut de tine insa fara var globale #include <avr/io.h>uint8_t a;uint8_t b;uint8_t func1() {return a+b;}uint8_t func2() {return a-b;}uint8_t func3() {return b-a;} uint8_t func4() {return b+a;}void main(){func1();func2();func3();func4();} asa am obtinut 140byti program si 2 date. P.s: evita folosirea var globale gen "rez" in locul functiei return, pentru ca folosesti mai putin ram. Link spre comentariu
Laci Postat Aprilie 8, 2011 Partajează Postat Aprilie 8, 2011 Ieri ma grabeam, asa ca corectie,completare:switch(op_type){case OP_ADUNARE:ret_val = op1+op2;break;case OP_SCADERE:ret_val = op1-op2;break;}//switch(op_type)cu functii asa de simple nu se poate demonstra technici de optimizare, operatiile poti sa pui direct in main, sau faci functiile inline. Dureaza 1-2 ani pana iti dezvolti un mod de gandire intr-un limbaj de programare, trebuie sa intelegi codul asm generat, cum lucreaza compilatorul si diferenta intre optimizare pentru viteza / marime cod. Link spre comentariu
claudio Postat Aprilie 8, 2011 Autor Partajează Postat Aprilie 8, 2011 Vina mea ... nu am specific ca aceste functii sunt pur informative!!!Programul meu arata mult mai complicat decat aceste functii de adunare scarede, dar nu avea rost sa incarc topicul.In principiu eu am fct1() si fct2() in care se executa mai multe operatii, apeleaza alte functii, etc. Diferenta dintre ele fiind foarte mica, din 40 randuri, sa zic, difera doar 1 sau 2.Cum ar fi de preferat? Sa fac o singura functie in care mai pun un "if(var)" pe linia respectiva, iar in main definesc inca o variabila, iar cand apelez functia folosesc:var=0; fct12();var=1; fact12();sau las doua functii si in main sa le apelez separat:fct1();fct2();Asta vreau sa inteleg, in executia programelor pe microcontroler, e mai bine daca e o singura functie care isi schimba modul de functioneare in functie de anumite variabile, sau se apeleaza separat doua functii care aparent fac cam aceleasi operatii.Sper ca am explicat bine ce vreau sa cer.PS: stiu matematica, stiu C, asm putin, fac programare de 2ani, dar cu optimizari nu mi-am batut pana acum capul. Link spre comentariu
adynis Postat Aprilie 8, 2011 Partajează Postat Aprilie 8, 2011 Ma gandesc ca, la cele 2 exemple din primul post, ai putea sa le compilezi si sa analizez codul ASM generat, poate deduc ceva de pe-acolo. Presupun ca depinde f. mult de cum transforma compilatorul codul in ASM, in cazul asta nu ar fi un raspuns general valabil. Link spre comentariu
Laci Postat Aprilie 8, 2011 Partajează Postat Aprilie 8, 2011 Daca diferenta intre cele 2 functii este mica atunci mai bine folosesti 1 functie + eventual inca un parametru, asa sigur optimizezi binarul generat. Ca si viteza este mai complicat ca 1 parametru in plus inseamna inca un registru incarcat inainte de apel si pus pe stiva, la return iarasi inca un pop, deci poate un overhead mai mare. Iarasi daca este functie mica poti sa-l faci inline dar daca este apelat de multe ori atunci grija mare ca creste binarul(hex). Link spre comentariu
claudio Postat Aprilie 8, 2011 Autor Partajează Postat Aprilie 8, 2011 Daca diferenta intre cele 2 functii este mica atunci mai bine folosesti 1 functie + eventual inca un parametru, asa sigur optimizezi binarul generat. Ca si viteza este mai complicat ca 1 parametru in plus inseamna inca un registru incarcat inainte de apel si pus pe stiva, la return iarasi inca un pop, deci poate un overhead mai mare. Iarasi daca este functie mica poti sa-l faci inline dar daca este apelat de multe ori atunci grija mare ca creste binarul(hex).Multumes pentru raspunsuri.O sa ma duc pe varianta unei singure functii si declarea unei variabile care va decide cum vor fi procesate datele.Nu este functie mica, nu pot face inline.Numarul de apelari a functiei va depinde doar de o valoare scrisa in eeprom, de utilizator. (probabil 1 la 1sec, sau 1 la 15sec) Link spre comentariu
Laci Postat Aprilie 8, 2011 Partajează Postat Aprilie 8, 2011 Cand am zis numarul de apeluri m-am referit unde-l folosesti de unde apelezi, nu daca pui intr-un ciclu Link spre comentariu
claudio Postat Aprilie 11, 2011 Autor Partajează Postat Aprilie 11, 2011 As mai avea nevoie si de alte sfaturi legate de alta sectiune din program, nu mai deschid alt topic. Programul este in felul urmator: Am o intrerupere de tipul CTC (ISR(TIMER1_COMPA_vect)) care imi activeaza apoi dezactiveaza cate un pin pe portul A, consecutiv. Alta intrerupere de tip ISR(USART_RXC_vect) care la primirea unui anumit caracter pe serial intra intr-o functie de scriere/citire memorie EEPROM. Mi se intampla in multe cazuri cand intra in functia de prelucrare date eeprom, sa ramana un anumit pin de pe portul A activat. Am rezolvat problema in felul urrmator, si functioneaza, vreau doar sa stiu daca e cea mai buna varianta: uint8_t programming_flag; //definesc o variabila pentru semnalizare intrare in programare eepromISR(TIMER1_COMPA_vect){ if(programming_flag==0) { //codul initial care ruleaza in ISR }}void WriteDemoTest(){ cli(); programming_flag=1; PORTA=0x00; //codul initial de prelucrare date din eeprom programming_flag=0; sei();} Link spre comentariu
Laci Postat Aprilie 11, 2011 Partajează Postat Aprilie 11, 2011 cli(), sei() este in plus. Link spre comentariu
claudio Postat Aprilie 13, 2011 Autor Partajează Postat Aprilie 13, 2011 cli(), sei() este in plus.initial am incercat doar cu cli() si sei(), dar nu a functionat, acum dupa ce am pus acel flag banuiesc ca le pot scoate Link spre comentariu
Laci Postat Aprilie 13, 2011 Partajează Postat Aprilie 13, 2011 ori pui cli/sei ori cu flag. daca folosesti librariile avr-gcc operatiile pe eeprom parca sunt atomice(nus 100% trebuie verificat in cod), oricum este deajuns sa protejezi scrierea citirea efectiva in eeprom nu toata functia. Link spre comentariu
Postări Recomandate
Creează un cont sau autentifică-te pentru a adăuga comentariu
Trebuie să fi un membru pentru a putea lăsa un comentariu.
Creează un cont
Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!
Înregistrează un nou contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum