Sari la conținut
ELFORUM - Forumul electronistilor

Sfaturi optimizare cod


claudio

Postări Recomandate

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
  • Răspunsuri 13
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • Laci

    6

  • claudio

    5

  • nana

    1

  • picolo

    1

Top autori în acest subiect

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

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

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
:speriat 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

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

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

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

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

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

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 cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări