simplex Postat Decembrie 12, 2011 Partajează Postat Decembrie 12, 2011 Compilatorul care merge cu AVR Studio 4.18, 4.19 genereaza un algoritm in limbaj de asamblare foarte incet pentru calcule cu numere float Ce setari trebuie sa fac pentru a accelera inmultirile de numere in virgula mobila. Compilator AVR Studio 4.18 uint16_t = uint8_t * uint8_t -> 10 Clock Cycles - REPEDE uint32_t = uint16_t * uint16_t -> 29 Clock Cycles - ACCEPTABIL float = float * float -> 2076 Clock Cycles - FOARTE INCET (a se vedea programul atasat) Este greu de crezut ca sunt necesari 2076 tacti pentru a efectua un produs float = float * float in timp ce doua cantitati intregi intre 0 si 65535 (uint32_t = uint16_t * uint16_t) sunt inmultite in doar 29 cicli. Programul folosit pentru testari este urmatorul: #include <avr/io.h>uint8_t i, s;volatile uint8_t a8, b8;volatile uint8_t p16;volatile uint16_t a16, b16;volatile uint32_t p32;volatile float af, bf;volatile float pf;int main(void){ a8=143; b8=249; a16=37453; b16=58274; af=374.367893; bf=58274.8982; for (i=1;i<5;i++) { p16 = a8 * b8; // CC -> 308 p32 = a16 * b16; // CC -> 318 pf = af * bf; // CC -> 347 s = 1; // CC -> 2423 }return 1;} Link spre comentariu
godFather89 Postat Decembrie 13, 2011 Partajează Postat Decembrie 13, 2011 Verifica asta: You are not linking in the math library from AVR-LibC. GCC has a library that is used for floating point operations, but it is not optimized for the AVR, and so it generates big code, or it could be incorrect. This can happen even when you are not using any floating point math functions from the Standard C library, but you are just doing floating point math operations.When you link in the math library from AVR-LibC, those routines get replaced by hand-optimized AVR assembly and it produces much smaller code. Link-uit math-ul si cu o simulare fara optimizari (oricum nu prea are ce optimiza) sunt necesari 1839 ciclii pentru o inmultire. Mi se pare destul de normal. Nu are instructiuni pentru operatii cu virgula mobila. Link spre comentariu
simplex Postat Decembrie 13, 2011 Autor Partajează Postat Decembrie 13, 2011 Link-uit math-ul si cu o simulare fara optimizari (oricum nu prea are ce optimiza) sunt necesari 1839 ciclii pentru o inmultire. Mi se pare destul de normal. Nu are instructiuni pentru operatii cu virgula mobila.Inmultirea a doua numere tip float este de fapt inmultirea a doi intregi (pe 32 biti de ex.) si adunarea altor doi (pe 8 biti de regula) deoarece orice cantitate cu virgula se poate scrie ca:float = intreg cu semn*10^(intreg cu semn) Din programul de mai jos rezulta clar ca numerele tip float af=45343454E-34, bf=-27474534E21 sunt inmultite in 2513 cicli, in timp ce facind un artificiu si lucrind separat cu mantisele si exponentii lui af si bf rezultatul final apare dupa doar 102 tacti adica de 24 ori mai repede, lucru care nu este de neglijat. Foarte sincer, impresia mea este ca uitam sa facem vreo setare in compilator sau in alta parte undeva prin AVR Studio si asta este cauza pentru care operatiile float * float sunt asa incete sau poate compilatorul nu este bun. #include <avr/io.h>#include <math.h>uint8_t i; volatile uint8_t q;volatile int8_t ae8, be8;volatile int16_t se16;volatile int32_t am32, bm32;volatile int64_t pm64;volatile float af, bf;volatile long pf;int main(void) { ae8=-34; be8=21; am32=45343454; bm32=-27474534; af=45343454E-34; bf=-27474534E21; for (i=1;i<5;i++) { pm64 = am32 * bm32; // CC -> 393 se16 = ae8 + be8; // CC -> 479 pf= af * bf; // CC -> 495 q = 1; // CC -> 3008 }return 1;} Link spre comentariu
nr4 Postat Decembrie 13, 2011 Partajează Postat Decembrie 13, 2011 Problema pe care nu o intelegi se rezuma la studiul arhitecturilor de microprocesoare."Artificiile" ce pentru creierul uman par logice, nu par la fel de logice pentru orice unitate ALU.Asa cum ti-a spus si godFather89, microcontroler-ul nu contine o unitate FPU sau macar ceva dedicat in acest sens, ca prin urmare compilatorul "este foarte bun".Recomand sa studiezi totusi ce face un compilator caci golurile sunt mari, probabil si din lipsa de documentare tehnica asupra microcontrolerelor atmega sau ce simulezi. Link spre comentariu
simplex Postat Decembrie 13, 2011 Autor Partajează Postat Decembrie 13, 2011 Recomand sa studiezi totusi ce face un compilator caci golurile sunt mari, probabil si din lipsa de documentare tehnica asupra microcontrolerelor atmega sau ce simulezi.1) Raspunsul nu este folositor. Alte ramarci nu mai fac deoarece as jigni.2) Keil uVision4 pentru 8051 genereaza cod assembler care face inmultiri float * float in mult mai putini tacti (de vreo 10 ori) decit codul echivalent generat de AVR Studio pentru procesoare AVR.Atit 8051 cit si AVR nu au Floating Point Hardware Multipliers, nu au instructiuni assembler dedicate inmultirii numerelor in virgula mobila, si cu toate astea 8051 este aparent de vreo 10 ori mai rapid.Este evident ca rapiditatea de calcul a produselor float * float in cazul lui 8051 nu se datoreaza lui insusi (arhitecturii interne si limbajului sau de asamblare) ci unui algoritm mai bun de generare a codului asembler din compilatorul lui Keil uVision4. Link spre comentariu
simplex Postat Decembrie 13, 2011 Autor Partajează Postat Decembrie 13, 2011 Verifica asta: You are not linking in the math library from AVR-LibC. GCC has a library that is used for floating point operations, but it is not optimized for the AVR, and so it generates big codeLink-uit math-ul si cu o simulare fara optimizari (oricum nu prea are ce optimiza) sunt necesari 1839 ciclii pentru o inmultire.Prin "Link-uit math-ul" ce se intelege de fapt, doar adaugarea unei linii #include dupa #include in codul C sau mai trebuiesc si alte setari? Link spre comentariu
simplex Postat Decembrie 13, 2011 Autor Partajează Postat Decembrie 13, 2011 Mesaj sters de autor. Link spre comentariu
godFather89 Postat Decembrie 13, 2011 Partajează Postat Decembrie 13, 2011 Prin "Link-uit math-ul" ce se intelege de fapt, doar adaugarea unei linii #include dupa #include in codul C sau mai trebuiesc si alte setari?-lm la linker. Inmultirea a doua numere tip float este de fapt inmultirea a doi intregi (pe 32 biti de ex.) si adunarea altor doi (pe 8 biti de regula) deoarece orice cantitate cu virgula se poate scrie ca:Nu chiar. Vezi standardul (IEE754) respectat. Link spre comentariu
simplex Postat Decembrie 13, 2011 Autor Partajează Postat Decembrie 13, 2011 -lm la linker.Stiu ca sunt plictisitor dar unde dau acel -lm la linker. Eu folosesc AVR Studio 4.18 si doar apas Build urmat de Run, nu stiu sa lucrez in linie de comanda.Am gasit calea asta:AVR Studio 4.18 / Meniu Project / Configuration Options / Libraries / Available link objects (libc.a, libm.a, + alte biblioteci) / Link with these objects.Adaug vreuna din bibliotecile de la lista "Available link objects" in caseta "Link with these objects"? Link spre comentariu
godFather89 Postat Decembrie 13, 2011 Partajează Postat Decembrie 13, 2011 libm.a este libraria de matematica. Edit: Am rulat codul cu optimizari de gradul 3 si au rezultat 159 ciclii per inmultire intre 2 float-uri. a=1.2456; //93b=1.1328; //105c = a*b; //117c = a*b; //276 Edit2: Si rulat pe codul tau: #include <avr/io.h>uint8_t i, s;volatile uint8_t a8, b8;volatile uint8_t p16;volatile uint16_t a16, b16;volatile uint32_t p32;volatile float af, bf;volatile float pf;int main(void){ a8=143; b8=249; a16=37453; b16=58274; af=374.367893; bf=58274.8982; for (i=1;i<5;i++) { p16 = a8 * b8; // CC -> 213 p32 = a16 * b16; // CC -> 223 pf = af * bf; // CC -> 251 s = 1; // CC -> 402 }return 1;} Link spre comentariu
nr4 Postat Decembrie 14, 2011 Partajează Postat Decembrie 14, 2011 Recomand sa studiezi totusi ce face un compilator caci golurile sunt mari, probabil si din lipsa de documentare tehnica asupra microcontrolerelor atmega sau ce simulezi. 1) Raspunsul nu este folositor. Alte ramarci nu mai fac deoarece as jigni. Foarte bine faci. uint16_t = uint8_t * uint8_t uint32_t = uint16_t * uint16_t Cu privire strict la codul de mai sus scris in C. Care este greseala lui simplex din codul de mai sus? (aviz amatorilor) Recomand ca orice test pe care il faceti, sa se termine cu verificarea rezultatelor, pentru a fi siguri ca ceea ce faceti este si corect. Numaratul ciclilor nu valideaza un calcul matematic!!! Link spre comentariu
simplex Postat Decembrie 14, 2011 Autor Partajează Postat Decembrie 14, 2011 libm.a este libraria de matematica. Am rulat codul cu optimizari de gradul 3 si au rezultat 159 ciclii per inmultire intre 2 float-uri. Deci printr-o simpla setare viteza de calcul a crescut de peste 10 ori. Link spre comentariu
godFather89 Postat Decembrie 14, 2011 Partajează Postat Decembrie 14, 2011 Deci printr-o simpla setare viteza de calcul a crescut de peste 10 ori.O exprimare mai corecta ar fi : "codul este de 10 ori mai optim/eficient". 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