Optimisation des accès mémoires

Programmation d'applications complexes
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Optimisation des accès mémoires

Message par G-Rom »

Je cherche à optimisé ceci :

Code : Tout sélectionner

Structure zbuffer
  *depth_buffer.i
  w.l
  h.l
EndStructure

ProcedureDLL.i zbuffer(w.l, h.l, mFar.f)
  *zb.zbuffer      = AllocateMemory(SizeOf(zbuffer))  
  *zb\depth_buffer = AllocateMemory( w * h * 4 )
  *zb\w            = w
  *zb\h            = h
  FillMemory(*zb\depth_buffer , MemorySize(*zb\depth_buffer), mFar, #PB_Long)
  ProcedureReturn *zb
EndProcedure

ProcedureDLL zbuffer_write(*zb.zbuffer,x.i, y.i, depth.f)
  If x=>0 And x < *zb\w And y=>0 And y < *zb\h
    PokeF(*zb\depth_buffer + (x*4) + *zb\w * (y*4), depth)
  EndIf
EndProcedure
  
ProcedureDLL.f zbuffer_read(*zb.zbuffer, x.i, y.i)
  If x=>0 And x < *zb\w And y=>0 And y < *zb\h
    ProcedureReturn PeekF(*zb\depth_buffer + (x*4) + *zb\w * (y*4))
  EndIf
EndProcedure
  
ProcedureDLL.f zbuffer_fill(*zb.zbuffer, value.f)
  FillMemory(*zb\depth_buffer , MemorySize(*zb\depth_buffer), value, #PB_Long)
EndProcedure


Buffer = zbuffer(640,480,1500)

A = ElapsedMilliseconds()
For i = 0 To 50
  For y = 0 To 480-1
    For x = 0 To 640
      zbuffer_write(Buffer,x,y,Random(1500))    
    Next 
  Next 
Next 
B = ElapsedMilliseconds()
WriteTime = B-A

A = ElapsedMilliseconds()
For i = 0 To 50
  For y = 0 To 480-1
    For x = 0 To 640
      zbuffer_read(Buffer,x,y) 
    Next 
  Next 
Next 
B = ElapsedMilliseconds()
ReadTime = B-A


MessageRequester("", "Ecriture = "+Str(WriteTime) + Chr(10) + "Lecture = " + Str(ReadTime))

Sur ma bécane j'obtiens en moyen 380ms pour l'écriture , 170ms pour la lecture.
Comment je pourrais descendre encore en temps ?
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

Re: Optimisation des accès mémoires

Message par case »

le random bouffe pas mal de vitesse

avec le random(1500° j'arrives a 318/219
sans j'arrive a 219/219
ImageImage
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Optimisation des accès mémoires

Message par G-Rom »

en passant par des macros je divise quasiment par deux le temps.
Quelqu'un peut me dire comment faire en ASM pour écrire dans une zone mémoire avec un offset ?
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Optimisation des accès mémoires

Message par djes »

D'abord, il faut que tu saches que tu n'auras pas la même vitesse selon les zones mémoire que tu adresses (mémoire vidéo vs RAM par exemple). D'autre part, il vaut mieux copier de gros blocs ; es-tu obligé de faire point par point?
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Optimisation des accès mémoires

Message par G-Rom »

En fait , au moment du dessin d'un triangle 3D , j'ai 3 point (ABC)
chaque point possède une position (XYZ) , (XY) correspond au coordonnées écran ( après transformation donc ) , le Z c'est sa position "spatiale" , en interpolant cette valeur suivant les point (ABC) je détermine avec précision la profondeur du triangle. au moment du dessin donc , si un autre triangle dans le z-buffer est déjà dessiner et si la valeur Z du buffer est plus petite , j'écris pas dedans.

Cela permet donc de faire du clipping sans faire de géométrie complexe sur les triangles , je me passe donc d'un quick sort des faces.
je suis donc obligé de le faire point par point , pour l'écriture & la lecture , pour le "blitage" du buffer à l'écran , je le fait d'un seul bloc.

J'utilise donc la RAM , pour stocker les valeurs du buffer, la mémoire vidéo ne me sert pas , ce n'est pas le but.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Optimisation des accès mémoires

Message par djes »

Ok, un z-buffer software. Es-tu obligé de le faire ainsi, car c'est extrêmement coûteux en temps machine? Tu vas devoir calculer tous les points de tous tes triangles, soit des millions d'opérations. De plus, as-tu une position Z corrigée par point (car là aussi, ça bouffe)? En général, on fait plutôt un backface culling, puis un quicksort, éventuellement un b-tree pour voir ce qui reste à calculer de visible, et seulement après le z-buffer (qui est nécessaire de toutes façons pour les textures). En tous cas, si tu travailles par triangle, tu as tout intérêt à ne pas faire d'appel à une procédure par point, mais bien une boucle hyper optimisée avec un maximum de valeurs dans les registres, que tu remplis avant la boucle. Tu peux ainsi éviter les empilements et les tests de débordements.

Par rapport à l'asm, en fait, PB génère un assez bon code (toujours optimisable), tu peux voir le résultat avec l'excellent PureASM d'Erix14... Tu t'en es déjà servi?
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Optimisation des accès mémoires

Message par G-Rom »

En fait , je ne mixe pas le QuickSort / Zbuffer , c'est soit l'un ou l'autre , le backface culling est indispensable pour optimisé les opérations sur le buffer.
tu as tout intérêt à ne pas faire d'appel à une procédure par point
Pour la rastérization , je n'ai pas le choix , quand je "plote" mon écran de pixel , je dois bien vérifier si j'ai le droit d'écrire dedans.
je vais donc passer par des macros.

Quand au texture , le zbuffer me servira juste pour faire un "brouillard"


PureASM ne marche pas sous linux ^^
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Optimisation des accès mémoires

Message par djes »

G-Rom a écrit :Pour la rastérization , je n'ai pas le choix , quand je "plote" mon écran de pixel , je dois bien vérifier si j'ai le droit d'écrire dedans.
je vais donc passer par des macros.
Pas forcément, si tu fais tout le rendu d'un triangle dans la même boucle...
G-Rom a écrit :PureASM ne marche pas sous linux ^^
Merde! M'enfin tu dois pouvoir récupérer le code asm quelque part, avec l'option qui va bien (/COMMENTED je crois)...
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Optimisation des accès mémoires

Message par G-Rom »

djes a écrit :
G-Rom a écrit :Pour la rastérization , je n'ai pas le choix , quand je "plote" mon écran de pixel , je dois bien vérifier si j'ai le droit d'écrire dedans.
je vais donc passer par des macros.
Pas forcément, si tu fais tout le rendu d'un triangle dans la même boucle...
Je ne te suis pas , comment veut tu j'écrive d'un bloc dans le buffer sachant que je ne connais pas à l'avance la profondeur quand je dessine mon triangle , tout en sachant que j'écris que si la valeur Z est plus petite que celle du buffer.

en gros :

- octree
- Projection de toutes les vertices
- backface culling
- pour chaque triangle
- on dessine
- pour chaque pixel
- on teste le buffer
- si z<zbuffer , on ecris dans un autre buffer la couleur du triangle. ( color buffer )
- on blit le <color buffer> à l'écran.


djes a écrit :
G-Rom a écrit :PureASM ne marche pas sous linux ^^
Merde! M'enfin tu dois pouvoir récupérer le code asm quelque part, avec l'option qui va bien (/COMMENTED je crois)...
oui , il me semble.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Optimisation des accès mémoires

Message par djes »

Quand tu vas dessiner ton triangle, tu vas avoir les coordonnées de tes 3 points, tu vas donc pouvoir (devoir!) faire un clipping en fonction de l'écran, avant le dessin. (s'il y en a un qui sort de l'écran, tu vas devoir recalculer une position interpolée). Du coup, tu n'auras absolument plus besoin de faire de test point par point.
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Optimisation des accès mémoires

Message par G-Rom »

A mon avis , tu ne me suis pas ^^
je suis d'accord avec toi pour le clipping.

Le Zbuffer n'est qu'un buffer de pronfondeur ( dans le code plus haut , je stocke que des floats ) , ce buffer à la même taille que mon écran. c'est une sorte de masque.
chaque float fait au départ la taille du zFar ( qui est la valeur max de rendu , au delà , y a rien , ou une skybox , mais on s'éloigne du sujet )
Chaque triangle au moment du dessins est déjà clippé.
Pour chaque pixel du triangle ( au moment de la rastérization donc ) j'interpole le Z , de cette manière , peut importe l'endroit sur la surface du triangle je connais sa profondeur. je consulte le zBuffer pour savoir si j'ai le droit de stocker un pixel. si la profondeur du pixel à dessiner est plus petite que celle du zbuffer , alors j'actualise mon zBuffer avec la nouvelle pronfondeur qui est plus petite et j'écris mon pixel à l'écran , sinon je passe au pixel suivant.

regarde se site sur lequel je me suis fait les dents : (dernier paragraphe)

http://membres.multimania.fr/heulin/3D/chap5.html
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Optimisation des accès mémoires

Message par djes »

Arf! Tu sais, je faisais déjà des z-buffers en 95/96 ; j'ai d'ailleurs inventé une méthode d'utilisation du blitter pour traiter le z-buffer sur Amiga, de façon à faire des sortes de vector-balls (d'autres formes aussi) gérées en z par pixel de façon hardware, puis je l'ai optimisé pour le CPU sur des entiers longs (je traitais 32 pixels à la fois, avec un z-buffer sur 32 bits). On pouvait manipuler d'énormes molécules en 3d en temps réel, tu vois le truc... Juste pour dire que je connais un peu!

Les bases de l'optim, c'est éliminer un maximum d'instructions. Tu dois bien sûr comparer au z de ton z-buffer, mais le test de dépassement de ton buffer est inutile. Quant au test du Z, il pourrait bien s'optimiser si tu traitais des paquets de données au lieu d'un pixel à la fois. Voilà où je voulais en venir :)
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Optimisation des accès mémoires

Message par G-Rom »

tu veut dire donc que je devrais lire le zBuffer pour savoir si j'écris dedans ou pas.
si oui , je stocke le pixel dans une sorte de buffer temporaire d'une taille a définir (64 pixel par exemple?)
et ensuite je blit le résultat dans le véritable zbuffer ?
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Optimisation des accès mémoires

Message par djes »

Oui, c'est à cela que servent les registres étendus, à traiter des paquets de données, comme par exemple des pixels, limiter le nombre d'accès mémoire ou uniquement en rafales. Il y a là à la fin un exemple : http://fr.wikipedia.org/wiki/Streaming_SIMD_Extensions
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Optimisation des accès mémoires

Message par G-Rom »

les instructions SSE , les registres 128 bits donc.
j'essaye d'adapté l'exemple sans succès...

Code : Tout sélectionner

Structure vector4
  x.f
  y.f
  z.f
  w.f
EndStructure


V1.vector4
V2.vector4
Vres.vector4

V1\x = 50
V1\y = 100
V1\z = 245
V1\w = 135

V2\x = 100
V2\y = 100
V2\z = 100
V2\w = 100



!LEA Esi, dword [v_V1]
!movaps xmm0, [Esi]
!LEA Esi, dword [v_V2]
!addps  xmm0,[Esi]
; !movaps [v_Vres],xmm0

; movaps xmm0,adresse-de-v1          ;xmm0=v1.w | v1.z | v1.y | v1.x 
; addps xmm0,adresse-de-v2           ;xmm0=v1.w+v2.w | v1.z+v2.z | v1.y+v2.y | v1.x+v2.x               
; movaps adresse-du-vec_res,xmm0 
Répondre