Documente Academic
Documente Profesional
Documente Cultură
Tema 1
2016
Tema const n realizarea unei proiect C pentru StarCore140 care s implementeze o funcie
care calculeaza N puncte date n vectorul x aflate pe o dreapt de pant p i care trece prin (x0,y0).
N este un numar multiplu de 4.
fid=fopen('..\date_intrare.dat','w','b');
fwrite(fid,x.*2^15,'int16');
fclose(fid);
Pentru a compensa modul de reprezentare diferit ale numerelor fracionare n cele dou
programe, Matlab si CodeWarrior, valoarea fiecrui element se nmulete cu 2^15.
De asemenea se calculeaz valorile vectorului y utiliznd Matlab pentru a putea compara cele
dou rezultate.
y=p*(x-x0)+y0
Dup ce se ruleaz funcia din programul C rezultatele sunt trecute ntr-un fiier ce este citit
de programul Matlab.
fid=fopen('..\rezultate.dat','r','b');
exit=fread(fid,N,'int16');
fclose(fid);
exit=exit/(2^15);
Se reprezint grafic rezultatele obinute prin cele doua metode pentru a observa diferenele
mai uor.
eroare=y-exit'
Vectorul coloana exit este transpus pentru a se putea efectua scderea deoarece y este un
vector linie.
int main()
{
Word16 x[DataBlockSize],y[DataBlockSize], p, x0, y0;
#pragma align x 8
#pragma align y 8
int i;
FILE *fp;
p = WORD16(0.7);
x0 = WORD16(0.95);
y0 = WORD16(0.8);
fp=fopen("../date_intrare.dat","r+b");
fread(x,sizeof(Word16),DataBlockSize,fp);
if (!fp)
printf("\nNu s-a deschis date_intrare.dat");
fclose(fp);
fp=fopen("../rezultate.dat","w+b");
fwrite(y,sizeof(Word16), DataBlockSize, fp);
if (!fp)
printf("\nNu s-a deschis rezultate.dat");
fclose(fp);
return(0);
}
int i;
for(i=0;i<DataBlockSize;i++)
{
y[i]=sub(x[i], x0);
y[i]=mult(y[i], p);
y[i]=add(y[i], y0);
}
Pentru programul neoptimizat bucla corespunztoare funciei are urmtorul cod de asamblare cu C:
LOOPSTART3
L7
DW3
[
move.f (r0)+,d0 ;[13,1]
move.f (sp-14),d4 ;[14,1]
]
DW4
sub d1,d0,d2 ;[13,1]
DW5
mac d2,d3,d4 ;[14,1]
DW6
moves.f d4,(r1)+ ;[13,1]
LOOPEND3
Se remarca faptul ca se execut o singur instruciune in fiecare ciclu main. Bucla conine 5
cicluri care trebuie executate de N=40 de ori.
for(i=0;i<DataBlockSize;i+=4)
{
v0=sub(x[i],x0);
v1=sub(x[i+1],x0);
v2=sub(x[i+2],x0);
v3=sub(x[i+3],x0);
v4=L_mult(p,v0);
v5=L_mult(p,v1);
v6=L_mult(p,v2);
v7=L_mult(p,v3);
v8=extract_h(v4);
v9=extract_h(v5);
v10=extract_h(v6);
v11=extract_h(v7);
y[i]=add(v8, y0);
y[i+1]=add(v9, y0);
y[i+2]=add(v10, y0);
y[i+3]=add(v11, y0);
}
Am folosit variabilele v0-v11 pentru a calcula valorile intermediare ale ecuaiei dreptei.
Bucla principala din codul assembler rezultat in urma compilrii programului C este urmtoarea:
LOOPSTART3
L22
DW25
[
moves.4f d0:d1:d2:d3,(r0)+ ;[46,16] 5%=1
move.4f (r1)+,d0:d1:d2:d3 ;[31,16] 0%=0
]
DW26
[
sub d4,d3,d8 ;[34,16] 1%=0
sub d4,d0,d5 ;[31,16] 1%=0
sub d4,d1,d6 ;[32,16] 1%=0
sub d4,d2,d7 ;[33,16] 1%=0
]
DW27
[
mpy d9,d8,d13 ;[39,16] 2%=0
mpy d9,d5,d10 ;[36,16] 2%=0
mpy d9,d6,d11 ;[37,16] 2%=0
mpy d9,d7,d12 ;[38,16] 2%=0
]
DW28
[
add d14,d13,d15 ;[49,16] 3%=0
add d14,d10,d0 ;[46,16] 3%=0
add d14,d11,d1 ;[47,16] 3%=0
add d14,d12,d2 ;[48,16] 3%=0
]
DW29
tfr d15,d3 ;[46,16] 4%=0
LOOPEND3
Se remarc faptul ca n interiorul unui ciclu main sunt efectuate 4 operaii. De asemenea
bucla este iterat de N/4 ori ceea ce reprezint o mbuntire fa de cazul n care se folosea o
singur unitate ALU.
5
De asemenea s-a evaluat eroare, aceasta fiind de ordinul 10 .