JnBiz
Messages postés18Date d'inscriptionmardi 18 avril 2006StatutMembreDernière intervention30 mai 2006
-
16 mai 2006 à 19:08
JnBiz
Messages postés18Date d'inscriptionmardi 18 avril 2006StatutMembreDernière intervention30 mai 2006
-
17 mai 2006 à 17:46
Bonjour,
Dans l'unité TMatrix que je développe, les matrices sont formées par des tableaux dynamique de type extended (10 octets).
Pour optimiser certaines routines je compte mettre un peu d'assembleur. Or je rencontre un réel problème d'accés en mémoire, en effet les données du tableaux dynamiques ne sont pas toujours placées là ou on les attend.
En fait on s'attendrait à ce que les données du début de la ligne n+1 soient placées juste après la fin de la ligne n. La plupart du temps c'est le cas (avec un saut de 128 bits entre chaques lignes), mais à certain moment cela ne marche pas.
Exemple: J'ai transformé une fonction qui marche parfaitement pour des variables statique, pour des variables dynamiques j'obient ceci: (j'ai juste rajouté le saut de 128 bits)
Les données sont ici de type double (64 bits)
function FastMul(M1,M2:TMatrix):TMatrix;
var i,q,c,n,RC,RCB,RC2:integer;
s:double;
pX,pY,pZ:pointer;
begin
RC:=M1.RowCount;
RC2:=RC+3; // le +3 est du au décalage de 128 bits+le saut de la colonne 0 (64 bits)
RCB:=(RC+3)*8;
n:=RC;
RESULT:=Zeros(RC,RC); //on met à zero la matrice
pX:=@M1.Cells[1,0]; //les premières données sont écrites à la colonne n° 1 => saut de 64 bits
pY:=@M2.Cells[1,0];
pZ:=@RESULT.Cells[1,0];
c:=0;
for i:=1 to n do begin
q:=(i-1)*(RC+3);
asm
push esi
push edi
push edx
push ecx
push ebx
push eax
finit
mov edx,0
@b2: //for edx:=1 to n do begin
mov ecx,i
sub ecx,1
imul ecx,RC2
add ecx,edx
shl ecx,3
add ecx,pX
add ecx,8
fld qword [ecx]
fst s //M1[i,k]
mov ecx,n
@b3: //for ecx:=n to downto 0 do begin
prefetch [edi+ecx*8-256] //fait gagner 40% !
fld qword [edi+ecx*8] //M2[k,j];
fmul st(0),st(1)
fld qword [esi+ecx*8]
faddp
fstp qword [esi+ecx*8] //M[i,j]:=M[i,j]+s*M2[k,j];
loopnz @b3
ffree st(0)
add edi,RCB //même saut de 128+64 bits
inc edx
cmp edx,n
jne @b2
pop eax
pop ebx
pop ecx
pop edx
pop edi
pop esi
fninit
end;
end;
end;
Après quelques tests, on constate que cette méthode fonctionne de manière totalement aléatoire (fonctionne 10 fois, puis bug etc).
Lors du déboguage, on constate que certaines lignes des matrices ne sont pas au bon endroit.
Voila, si vous pouvez m'aider, merci d'avance.
DeltaFX
Messages postés449Date d'inscriptionlundi 19 avril 2004StatutMembreDernière intervention 8 avril 20092 16 mai 2006 à 20:53
Je crois que c'est indémer...able. Si je ne m'abuse, c'est zindoz qui s'occupe du bigntz, et pour faire court, ca fragmente en Ram. Et la, pour les sauts ahem,....
J'en connais pas assez en delphi, mais a priori il existe des composants plus adapté, genre TobjetList, Tcontnr... que l'on doit pouvoir packer avant manip asm.
Ou alors, si tu veux de l'asm, de la meme manière qu'on évitera en graphisme avancé d'utiliser du 24 bit (format batard, quelle idée d'avoir 3 octets, c'est chiant 3, comme puissance de 2....), de la meme manière que dans certain cas de Simul Num ( sur machines parralleles) on prefere alourdir le maillage pour pouvoir basculer des bancs memoires complet, il faudra peut-être éviter le dynamique pur.
JnBiz
Messages postés18Date d'inscriptionmardi 18 avril 2006StatutMembreDernière intervention30 mai 2006 16 mai 2006 à 22:37
Effectivement ca a l'air compliqué, je me demande quand même ce qui est contenu dans ces 128 bits mystère, peut être bien qu'il s'y trouve l'adresse de la ligne (je m'avance) car je ne vois pas trop à quoi ca peut servir d'autre, j'imagine qu'il doit y avoir un truc du genre : bloc mémoire alloué à la ligne (sur 32 bits) adresse mémoire du prochain bloc (sur 32 bits)...
En tous cas ca n'a pas l'air pratique.
Ne peut on pas alors envisager la création dynamique de tableaux statiques ? c'est peut être ce que tu sous-entends en parlant de dynamique pur. Ca me faciliterait grandement la tâche et pour l'utilisation de la mémoire c'est toujours mieux d'utiliser des variables alignées.
@DeltaFX : aucun probleme pour le 24bit, il est stocké dans un 32bits. et puis en asm on manipule les bits pas les octets donc comme 24 est une puissance de 2 ... ca pose aucun probleme ...
donc par exemple :
non franchement je vois pas ou est le probleme, vus que de toute façon il n'existe pas de registre 24 bits et que dans une couleur 32 bits le dernier octet correspond a l'alpha on aurait donc :
var r,g,b,a : byte;
asm
MOV EAX,{RGBA};
MOV r,AL;
MOV g,AH;
SHR EAX,16;
MOV b,AL;
MOV a,AH;
end;
donc aucune difference dans la manipulation d'un octet d'une couleur 32 ou 24 bits.
JnBiz
Messages postés18Date d'inscriptionmardi 18 avril 2006StatutMembreDernière intervention30 mai 2006 17 mai 2006 à 17:46
foxi, non, on compte bien "en marche avant", mais le problème n'est pas la, certaines données de tableaux dynamique ne sont pas situées juste après les dernières.
Yvessimon, je suis d'accord avec toi, seulement ce n'est vraiment pas pratique de mettre à chaque fois le i*col, d'autant que le nombre de colonnes change.