Plot VS Sprite VS Poke

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

erix14 a écrit :Les pointeurs sont plus rapides que les POKE, quand on travaille avec la mémoire cache il n'y a aucun doute. Quand on travaille avec la mémoire vidéo, on est limité par la bande passante inférieure à celle de la mémoire cache. Là, le transfert de données est plafonné et le microprocesseur a largement le temps d'exécuter des POKE...
si j'ai bien compris le plus rapide serait alors de charger un sprite avec l'option #PB_Sprite_Memory et d'utiliser les pointeurs que du coup ça serait beaucoup plus rapide que les tests qu'on a fait pour l'instant c'est ça ?
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

j'ai fait un test en modifiant le code et bien c'est plus lent lorsqu'on passe par la mémoire central que par celle de la carte video...enfin si mon code est bon...

Code : Tout sélectionner

InitSprite() 
OpenScreen(800,600,32,"PEEK AND POKE VS POINTER  :D ") 
CreateSprite(0,800,600)
Structure Pixel 
  Pixel.l 
EndStructure : Global *Ptr.Pixel :  Global *Poke.l 


Declare PointerDrawScreen() 
Declare PointerDrawSprite() 


PTR.l = PointerDrawScreen() 
PTR2.l= PointerDrawSprite() 

CloseScreen() 

MessageRequester("","POinteur Screen= "+Str(PTR)+"ms"+Chr(10)+" Pointeur Sprite = "+Str(PTR2)+"ms") 


Procedure PointerDrawScreen() 
Protected DBuffer.l,DBufferP.l,PixelFormat.l,Pbyte.l 
Protected TA.l,TB.l 

TA=ElapsedMilliseconds() 
StartDrawing(ScreenOutput()) 

    For i = 1 To 100 
    DBuffer      = DrawingBuffer() 
    DBufferP     = DrawingBufferPitch() 
    PixelFormat  = DrawingBufferPixelFormat() 

                      Select PixelFormat 
                            Case #PB_PixelFormat_8Bits         : PixelFormat=1 
                            Case #PB_PixelFormat_15Bits        : PixelFormat=2 
                            Case #PB_PixelFormat_16Bits        : PixelFormat=2 
                            Case #PB_PixelFormat_24Bits_RGB    : PixelFormat=3 
                            Case #PB_PixelFormat_24Bits_BGR    : PixelFormat=3 
                            Case #PB_PixelFormat_32Bits_RGB    : PixelFormat=4 
                            Case #PB_PixelFormat_32Bits_BGR    : PixelFormat=4 
                      EndSelect 
    
    For y = 0 To 600-1 
      *Ptr = DBuffer+DBufferP*y 
        For x = 0 To 800-1 
          *Ptr\Pixel = RGB(0,(y*100)/255,0) 
          *Ptr + PixelFormat 
        Next 
    Next 
    Next i 
StopDrawing() 
TB=ElapsedMilliseconds() 
ProcedureReturn TB-TA 
EndProcedure 

Procedure PointerDrawSprite() 
Protected DBuffer.l,DBufferP.l,PixelFormat.l,Pbyte.l 
Protected TA.l,TB.l 

TA=ElapsedMilliseconds() 
StartDrawing(SpriteOutput(0)) 

    For i = 1 To 100 
    DBuffer      = DrawingBuffer() 
    DBufferP     = DrawingBufferPitch() 
    PixelFormat  = DrawingBufferPixelFormat() 

                      Select PixelFormat 
                            Case #PB_PixelFormat_8Bits         : PixelFormat=1 
                            Case #PB_PixelFormat_15Bits        : PixelFormat=2 
                            Case #PB_PixelFormat_16Bits        : PixelFormat=2 
                            Case #PB_PixelFormat_24Bits_RGB    : PixelFormat=3 
                            Case #PB_PixelFormat_24Bits_BGR    : PixelFormat=3 
                            Case #PB_PixelFormat_32Bits_RGB    : PixelFormat=4 
                            Case #PB_PixelFormat_32Bits_BGR    : PixelFormat=4 
                      EndSelect 
    
    For y = 0 To 600-1 
      *Ptr = DBuffer+DBufferP*y 
        For x = 0 To 800-1 
          *Ptr\Pixel = RGB(0,(y*100)/255,0) 
          *Ptr + PixelFormat 
        Next 
    Next 
    Next i 
StopDrawing() 
TB=ElapsedMilliseconds() 
ProcedureReturn TB-TA 
EndProcedure 

erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message par erix14 »

Si tu dois beaucoup travailler sur ton Sprite, il vaut mieux le faire en mémoire cache et transféré le résultat en mémoire vidéo (comme l'avait souligné djes)
PS: Ton code n'est pas bon, dans les deux cas du travail avec la mémoire vidéo. (le Sprite est dans la mémoire vidéo)
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

erix14 a écrit :Si tu dois beaucoup travailler sur ton Sprite, il vaut mieux le faire en mémoire cache et transféré le résultat en mémoire vidéo (comme l'avait souligné djes)
PS: Ton code n'est pas bon, dans les deux cas du travail avec la mémoire vidéo. (le Sprite est dans la mémoire vidéo)
Oui j'ai un gros sprite ou je travaille sur chaque pixel tout le temps (genre de raytracing) mon code n'est pas bon ? pourtant j'utilise un sprite créer en mémoire cache non ? Est ce que tu pourrais me donné un exemple ou une piste comment faire ? :P
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message par erix14 »

En fait, si les transferts CPU <-> mémoire sont noyés dans un tas de calcul qui prennent beaucoup de temps, il est inutile d'optimiser ces transferts...
Voici un exemple où ça devient intéressant, il n'y a aucun calcul et le Sprite est suffisamment petit pour que le CPU optimise le travail avec la mémoire cache.

Code : Tout sélectionner

InitSprite()
OpenScreen(800,600,32,"PEEK AND POKE VS POINTER  :D ")
CreateSprite(0,255,255,#PB_Sprite_Memory)
Structure Pixel
     Pixel.l
EndStructure : Global *Ptr.Pixel :  Global *Poke.l


Declare PointerDrawScreen()
Declare PointerDrawSprite()


PTR.l = PointerDrawScreen()
PTR2.l= PointerDrawSprite()

CloseScreen()

MessageRequester("","POinteur Screen= "+Str(PTR)+"ms"+Chr(10)+" Pointeur Sprite = "+Str(PTR2)+"ms")


Procedure PointerDrawScreen()
     Protected DBuffer.l,DBufferP.l,PixelFormat.l,Pbyte.l
     Protected TA.l,TB.l
     
     TA=ElapsedMilliseconds()
     StartDrawing(ScreenOutput())
     
     For i = 1 To 100
          DBuffer      = DrawingBuffer()
          DBufferP     = DrawingBufferPitch()
          PixelFormat  = DrawingBufferPixelFormat()
          
          Select PixelFormat
               Case #PB_PixelFormat_8Bits         : PixelFormat=1
               Case #PB_PixelFormat_15Bits        : PixelFormat=2
               Case #PB_PixelFormat_16Bits        : PixelFormat=2
               Case #PB_PixelFormat_24Bits_RGB    : PixelFormat=3
               Case #PB_PixelFormat_24Bits_BGR    : PixelFormat=3
               Case #PB_PixelFormat_32Bits_RGB    : PixelFormat=4
               Case #PB_PixelFormat_32Bits_BGR    : PixelFormat=4
          EndSelect
          
          For y = 0 To 255-1
               *Ptr = DBuffer+DBufferP*y
               For x = 0 To 255-1
                    *Ptr\Pixel = 10;RGB(0,(y*100)/255,0)
                    *Ptr + PixelFormat
               Next
          Next
     Next i
     StopDrawing()
     TB=ElapsedMilliseconds()
     ProcedureReturn TB-TA
EndProcedure

Procedure PointerDrawSprite()
     Protected DBuffer.l,DBufferP.l,PixelFormat.l,Pbyte.l
     Protected TA.l,TB.l
     
     TA=ElapsedMilliseconds()
     StartDrawing(SpriteOutput(0))
     
     For i = 1 To 100
          DBuffer      = DrawingBuffer()
          DBufferP     = DrawingBufferPitch()
          PixelFormat  = DrawingBufferPixelFormat()
          
          Select PixelFormat
               Case #PB_PixelFormat_8Bits         : PixelFormat=1
               Case #PB_PixelFormat_15Bits        : PixelFormat=2
               Case #PB_PixelFormat_16Bits        : PixelFormat=2
               Case #PB_PixelFormat_24Bits_RGB    : PixelFormat=3
               Case #PB_PixelFormat_24Bits_BGR    : PixelFormat=3
               Case #PB_PixelFormat_32Bits_RGB    : PixelFormat=4
               Case #PB_PixelFormat_32Bits_BGR    : PixelFormat=4
          EndSelect
          
          For y = 0 To 255-1
               *Ptr = DBuffer+DBufferP*y
               For x = 0 To 255-1
                    *Ptr\Pixel = 10;RGB(0,(y*100)/255,0)
                    *Ptr + PixelFormat
               Next
          Next
     Next i
     StopDrawing()
     TB=ElapsedMilliseconds()
     ProcedureReturn TB-TA
EndProcedure 
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

interessant ta demonstration... finalement la seul façon d'optimisé est d'optimisé les calcules des couleurs....

dans mon code je ne sais pas trop comment optimisé la chose...
voici le test que j'ai fait il y a un certain temps maintenant... mes ce sujets m'a donné envis de m'y remettre
l'idée est de faire un jeu en 2D un peu dans le style d'Alien Breed ou les personnages se promènent avec des lampes torches... la lumière ne dois pas passer a travers les murs donc c'est du lancer de rayon et tout ce fait pixel part pixel ...

voici un lien avec la source pour voir
File:1->Light_engine.zip
Image
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message par erix14 »

Oui la seule façon d'optimiser est d'optimiser le calcul des couleurs avec des pointeurs et des structures. Tu fais beaucoup de calcul alors je ne pense pas que tu seras limité par la bande passante de la mémoire. Dans les exemples de djes, les pointeurs, les Poke et les Plot étaient tous au même niveau de performance car ils butaient tous sur cette fameuse bande passante.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

On peut quand même bien optimiser en codant en assembleur directement. D'ailleurs, ce serait intéressant de faire un test avec une bonne routine ASM de copie, non?

C'est quand même pour des cas spécifiques, car il faut vivre avec son temps, et les cartes graphiques d'aujourd'hui sont capables de bien des prouesses.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

djes a écrit :On peut quand même bien optimiser en codant en assembleur directement. D'ailleurs, ce serait intéressant de faire un test avec une bonne routine ASM de copie, non?

C'est quand même pour des cas spécifiques, car il faut vivre avec son temps, et les cartes graphiques d'aujourd'hui sont capables de bien des prouesses.
Je connais pas l'Assembleur :(
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message par erix14 »

Il existe déjà une bonne routine de copie : CopyMemoryAMD
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

erix14 a écrit :Il existe déjà une bonne routine de copie : CopyMemoryAMD
J'ai compris comment marchait la fonction mais je vois pas trop comment ça peut remplacer un pointeur ou un poke...enfin comment l'utilisé quoi ... :roll:
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Cool! Je l'avais oubliée celle-là :D
Alors est-ce qu'il est possible de s'en servir pour faire une copie du sprite de la mémoire centrale vers la mémoire vidéo plus rapide qu'avec les sprites FX? Je ne pense pas mais bon ;)
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message par erix14 »

@Thyphoon: la fonction CopyMemoryAMD était une parenthèse, tu dois déjà optimisées tes calculs de lumière. Après, est-ce qu'il faut directement traité avec la mémoire vidéo ou non, c'est la deuxième partie du problème. Déjà, trouve le FPS sans tes calculs de lumière puis avec les calculs. Si tu as 25 FPS avec calculs et plus de 100 FPS sans, ça ne servira pas beaucoup d'optimiser les transferts de données car c'est clair que c'est les calculs qui ralentissent le FPS.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Merci Erix14 pour tes conseilles... je vais m'atteler a ça dans les jours qui viennent...en plus je viens d'avoir une idée.....
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Bon j'ai réussi a sacrément optimisé la chose, mais du coup ce n'est plus vraiment le sujet du topic...donc pour ceux que ça interesse la suite est là
Défi Fonction 2D d'éclairage super optimisé
8)
Répondre