Problème avec la mémoire, Point(), et Plot()

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

djes a écrit :

Code : Tout sélectionner

CreateImage(1,512,512,24)
Y'aurait pas un souci? :lol:

Un indice? Faudrait peut-être tracer quelque chose pour pouvoir comparer... :twisted:

il trace bien quelque chose !! 8O

puisqu'a chaque procedure il fait :

Code : Tout sélectionner

StartDrawing(ImageOutput(1))
  
  For X=0 To ImageWidth(1)
    For Y=0 To ImageHeight(1)
      Plot(X,Y,$FFFFFF)
    Next Y
  Next X
  
StopDrawing()
ps : il est ou le soucis ??

??? 8O
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Message par Octavius »

Mes résultats avec le traçage d'un point sur un Sprite :
La fonction de Cpl.Bator & Dobro rapide_Plot() : 109 ms
La fonction native Plot() : 47 ms
(Ma fonction perso PlotMemory() ne peut pas tracer sur un Sprite...)

Finalement la fonction de Cpl.Bator est plus lente que le Plot() natif... Pouvez-vous confirmer ça ?

Mon code pour le test :

Code : Tout sélectionner

Procedure.l ReverseRGB(Color.l)
  ProcedureReturn RGB(Blue(Color),Green(Color),Red(Color))
EndProcedure

Procedure.l PointMemory(Image.l,X.l,Y.l)
  Protected bmp.BITMAP,Color.l,Width.l,Height.l,Depth.b,Offset.b,*Address
  
  ;On initialise la taille de l'image
  Width=ImageWidth(Image)
  Height=ImageHeight(Image)
  Depth=ImageDepth(Image)/8
  
  ;On vérifie les coordonnées
  If X<0 Or X>Width-1 Or Y<0 Or Y>Height-1
    ProcedureReturn -1
  EndIf
  
  ;Adresse de l'image
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp)
  ;Adresse de l'image
  *Address=bmp\bmBits
  ;Longueur en octets d'une ligne
  Offset=bmp\bmWidthBytes
  
  ;Récupération de la couleur du point
  If *Address
    CopyMemory(*Address+X*Depth+Y*Offset,@Color,Depth)
  EndIf
  
  ;Attention à bien inverser les conventions BGR et RGB
  ProcedureReturn ReverseRGB(Color)
  
EndProcedure

Procedure.b PlotMemory(Image.l,X.l,Y.l,Color.l)
  Protected bmp.BITMAP,Width.l,Height.l,Depth.b,Offset.l,*Address
  
  ;On initialise la taille de l'image
  Width=ImageWidth(Image)
  Height=ImageHeight(Image)
  Depth=ImageDepth(Image)/8
  
  ;On vérifie les coordonnées
  If X<0 Or X>Width-1 Or Y<0 Or Y>Height-1
    ;Echec de l'opération
    ProcedureReturn #False
  EndIf
  
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp)
  ;Adresse de l'image
  *Address=bmp\bmBits
  ;Longueur en octets d'une ligne
  Offset=bmp\bmWidthBytes
  
  ;Inversion de la convention RGB et BGR
  Color=ReverseRGB(Color)
  ;Collage du point dans l'image
  If *Address
    CopyMemory(@Color,*Address+X*Depth+Y*Offset,Depth)
  EndIf
  ;Réussite de l'opération
  ProcedureReturn #True
  
EndProcedure

Procedure rapide_Point(x,Y)   
  ;  AdresseVideo  = Buffer + ( x * PF ) + (BufferP/PF) * (y * PF)
  Select DrawingBufferPixelFormat() 
      Case #PB_PixelFormat_16Bits:PF=2 
          color = PeekW( DrawingBuffer()  + (x * PF) +(DrawingBufferPitch()/PF)* ( Y*PF ) ) 
      Case #PB_PixelFormat_32Bits_RGB    : PF=4
          color= PeekL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y*PF )  )
      Case #PB_PixelFormat_32Bits_BGR    : PF=4
          color= PeekL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y*PF )  )
          rouge=Red(color)
          vert=Green(color)
          bleu=Blue(color)
          color=RGB(bleu,vert,rouge) 
  EndSelect
  ProcedureReturn color
EndProcedure

Procedure rapide_Plot(x,Y,color)   
  ;  AdresseVideo  = Buffer + ( x * PF ) + (BufferP/PF) * (y * PF)
  Select DrawingBufferPixelFormat()
    Case #PB_PixelFormat_16Bits :PF=2
      rouge=Red(color)
      vert=Green(color)
      bleu=Blue(color)
      color=RGB(bleu,vert,rouge)   
      color=color>>2   
      PokeW( DrawingBuffer()  + (x * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) , color )
    Case #PB_PixelFormat_32Bits_RGB    : PF=4:t=0
      PokeL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) ,color )
    Case #PB_PixelFormat_32Bits_BGR    : PF=4:t=1 
      rouge=Red(color)
      vert=Green(color)
      bleu=Blue(color)
      color=RGB(bleu,vert,rouge)
    PokeL(DrawingBuffer() + (x * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) ,color )
  EndSelect
EndProcedure

InitSprite()
OpenScreen(800,600,32,"")
CreateFile(0,"save.txt")

;*********************************************

CreateSprite(0,1024,1024)

Time=GetTickCount_()

If StartDrawing(SpriteOutput(0))
  For X=0 To SpriteWidth(0)-1
    For Y=0 To SpriteHeight(0)-1
      rapide_Plot(X,Y,$FFFFFF)
    Next Y
  Next X
StopDrawing() : EndIf

Time=GetTickCount_()-Time

WriteStringN(0,"La fonction de Cpl.Bator & Dobro rapide_Plot() : "+Str(Time)+" ms")
SaveSprite(0,"image1.bmp")

;*********************************************

CreateSprite(0,1024,1024)

Time=GetTickCount_()

If StartDrawing(SpriteOutput(0))
  For X=0 To SpriteWidth(0)-1
    For Y=0 To SpriteHeight(0)-1
      Plot(X,Y,$FFFFFF)
    Next Y
  Next X
StopDrawing() : EndIf

Time=GetTickCount_()-Time

WriteStringN(0,"La fonction native Plot() : "+Str(Time)+" ms")
SaveSprite(0,"image2.bmp")
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

plutot que d'ecrire un fichier pour les resultats, tu peux faire comme ça aussi :)

Code : Tout sélectionner

Procedure.l ReverseRGB(Color.l)
  ProcedureReturn RGB(Blue(Color),Green(Color),Red(Color))
EndProcedure

Procedure.l PointMemory(Image.l,X.l,Y.l)
  Protected bmp.BITMAP,Color.l,Width.l,Height.l,Depth.b,offset.b,*Address
  
  ;On initialise la taille de l'image
  Width=ImageWidth(Image)
  Height=ImageHeight(Image)
  Depth=ImageDepth(Image)/8
  
  ;On vérifie les coordonnées
  If X<0 Or X>Width-1 Or Y<0 Or Y>Height-1
    ProcedureReturn -1
  EndIf
  
  ;Adresse de l'image
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp)
  ;Adresse de l'image
  *Address=bmp\bmBits
  ;Longueur en octets d'une ligne
  offset=bmp\bmWidthBytes
  
  ;Récupération de la couleur du point
  If *Address
    CopyMemory(*Address+X*Depth+Y*offset,@Color,Depth)
  EndIf
  
  ;Attention à bien inverser les conventions BGR et RGB
  ProcedureReturn ReverseRGB(Color)
  
EndProcedure

Procedure.b PlotMemory(Image.l,X.l,Y.l,Color.l)
  Protected bmp.BITMAP,Width.l,Height.l,Depth.b,offset.l,*Address
  
  ;On initialise la taille de l'image
  Width=ImageWidth(Image)
  Height=ImageHeight(Image)
  Depth=ImageDepth(Image)/8
  
  ;On vérifie les coordonnées
  If X<0 Or X>Width-1 Or Y<0 Or Y>Height-1
    ;Echec de l'opération
    ProcedureReturn #False
  EndIf
  
  GetObject_(ImageID(Image),SizeOf(BITMAP),@bmp)
  ;Adresse de l'image
  *Address=bmp\bmBits
  ;Longueur en octets d'une ligne
  offset=bmp\bmWidthBytes
  
  ;Inversion de la convention RGB et BGR
  Color=ReverseRGB(Color)
  ;Collage du point dans l'image
  If *Address
    CopyMemory(@Color,*Address+X*Depth+Y*offset,Depth)
  EndIf
  ;Réussite de l'opération
  ProcedureReturn #True
  
EndProcedure

Procedure rapide_Point(X,Y)   
  ;  AdresseVideo  = Buffer + ( x * PF ) + (BufferP/PF) * (y * PF)
  Select DrawingBufferPixelFormat()
    Case #PB_PixelFormat_16Bits:PF=2
      Color = PeekW( DrawingBuffer()  + (X * PF) +(DrawingBufferPitch()/PF)* ( Y*PF ) )
    Case #PB_PixelFormat_32Bits_RGB    : PF=4
      Color= PeekL(DrawingBuffer() + (X * PF) +(DrawingBufferPitch()/PF)* ( Y*PF )  )
    Case #PB_PixelFormat_32Bits_BGR    : PF=4
      Color= PeekL(DrawingBuffer() + (X * PF) +(DrawingBufferPitch()/PF)* ( Y*PF )  )
      rouge=Red(Color)
      vert=Green(Color)
      bleu=Blue(Color)
      Color=RGB(bleu,vert,rouge)
  EndSelect
  ProcedureReturn Color
EndProcedure

Procedure rapide_Plot(X,Y,Color)   
  ;  AdresseVideo  = Buffer + ( x * PF ) + (BufferP/PF) * (y * PF)
  Select DrawingBufferPixelFormat()
    Case #PB_PixelFormat_16Bits :PF=2
      rouge=Red(Color)
      vert=Green(Color)
      bleu=Blue(Color)
      Color=RGB(bleu,vert,rouge)   
      Color=Color>>2   
      PokeW( DrawingBuffer()  + (X * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) , Color )
    Case #PB_PixelFormat_32Bits_RGB    : PF=4:t=0
      PokeL(DrawingBuffer() + (X * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) ,Color )
    Case #PB_PixelFormat_32Bits_BGR    : PF=4:t=1
      rouge=Red(Color)
      vert=Green(Color)
      bleu=Blue(Color)
      Color=RGB(bleu,vert,rouge)
      PokeL(DrawingBuffer() + (X * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) ,Color )
  EndSelect
EndProcedure



;*********************************************

InitSprite()
OpenScreen(800,600,32,"")

CreateSprite(0,1024,1024)

time=GetTickCount_()

If StartDrawing(SpriteOutput(0))
    For X=0 To SpriteWidth(0)-1
      For Y=0 To SpriteHeight(0)-1
        rapide_Plot(X,Y,$FFFFFF)
      Next Y
    Next X
StopDrawing() : EndIf

time=GetTickCount_()-time

If StartDrawing(ScreenOutput())
DrawText(10,10,"La fonction de Cpl.Bator & Dobro rapide_Plot() : "+Str(time)+" ms",RGB(255,255,255),RGB(0,0,0))
SaveSprite(0,"image1.bmp")
EndIf
FlipBuffers()
;*********************************************

CreateSprite(0,1024,1024)

time=GetTickCount_()

If StartDrawing(SpriteOutput(0))
    For X=0 To SpriteWidth(0)-1
      For Y=0 To SpriteHeight(0)-1 
        Plot(X,Y,$FFFFFF)
      Next Y
    Next X
StopDrawing() : EndIf

time=GetTickCount_()-time
If StartDrawing(ScreenOutput())
    DrawText(10,10,"La fonction native Plot() : "+Str(time)+" ms",RGB(255,255,255),RGB(0,0,0))
    SaveSprite(0,"image2.bmp")
  EndIf
  FlipBuffers()
  Delay(3000)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

il reste que Fred nous avait dit que Plot() etait tres optimisé !!

les fonction "Rapide_" ont eu surtout pour but d'accelerer la fonction Point()
qui elle est tres tres lente en purebasic :)
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Message par Octavius »

Zut alors. Donc ça sert à rien d'essayer d'optimiser Plot(), particulièrement avec les dernières versions PB, c'est ça ?

Je vais essayer avec Point() pour voir.
Anonyme

Message par Anonyme »

Finalement la fonction de Cpl.Bator est plus lente que le Plot() natif... Pouvez-vous confirmer ça ?
C'est toi qui à alourdi la fonction , beaucoup de superflu la dedans :

Code : Tout sélectionner

Procedure rapide_Plot(X,Y,Color)   
  ;  AdresseVideo  = Buffer + ( x * PF ) + (BufferP/PF) * (y * PF)
  Select DrawingBufferPixelFormat()
    Case #PB_PixelFormat_16Bits :PF=2
      rouge=Red(Color)
      vert=Green(Color)
      bleu=Blue(Color)
      Color=RGB(bleu,vert,rouge)   
      Color=Color>>2   
      PokeW( DrawingBuffer()  + (X * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) , Color )
    Case #PB_PixelFormat_32Bits_RGB    : PF=4:t=0
      PokeL(DrawingBuffer() + (X * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) ,Color )
    Case #PB_PixelFormat_32Bits_BGR    : PF=4:t=1
      rouge=Red(Color)
      vert=Green(Color)
      bleu=Blue(Color)
      Color=RGB(bleu,vert,rouge)
      PokeL(DrawingBuffer() + (X * PF) +(DrawingBufferPitch()/PF)* ( Y *PF) ,Color )
  EndSelect
EndProcedure 
Crois tu changer de format de pixel entre deux tracage de pixel ?
Garde que le pokel , vire le reste , passe ta procedure en macro.
tu aura un plot , un poil optimisé.

Procedure rapide_Plot(X,Y,Color)

rouge=Red(Color)
vert=Green(Color)
bleu=Blue(Color)
Color=RGB(bleu,vert,rouge)
Tu passes en paramètre une couleur complète (RGB) puis dans la fonction tu extrait toute les couleur red(),etc... pour la ré assembler après...
pas très logique , et pas optimisé du tout , 4 appel de fonction inutile.



En espérant t'avoir aidé a optimisé tes sources.
@++
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Message par Octavius »

Oui beaucoup! Merci pour tes conseils!

Pourquoi une macro au fait ? L'appel à une procédure est-il spécialement lent ? Est-ce que pour gagner en rapidité on ne pourrait pas avoir recours à un sous-programme avec Gosub et Return ?
Neosis
Messages : 113
Inscription : dim. 24/févr./2008 20:11

Message par Neosis »

Octavius a écrit :Oui beaucoup! Merci pour tes conseils!

Pourquoi une macro au fait ? L'appel à une procédure est-il spécialement lent ? Est-ce que pour gagner en rapidité on ne pourrait pas avoir recours à un sous-programme avec Gosub et Return ?

Tien j'étais justement en train de m'interroger sur Gosub et Retour... moi aussi ça m'intéresse de savoir si c'est pas plus rapide. :wink:
Avatar de l’utilisateur
Ouaf-Ouaf
Messages : 212
Inscription : dim. 11/juil./2004 9:07

Message par Ouaf-Ouaf »

J'me suis posé la question en lisant ce post, surtout que j'utilise uniquement les Gosub et j'me demandais si c etait pas un defaut..

Avec ça, bon je sais pas si ça vaux quelque chose, j'ai des differences ridicules :

Macro Inc(Val)
Val = Val + 1
EndMacro


TopA = ElapsedMilliseconds()
While A < 1000000000
Gosub Inc
Wend
TopA = ElapsedMilliseconds() - TopA


TopB = ElapsedMilliseconds()
While B < 1000000000
Inc(B)
Wend
TopB = ElapsedMilliseconds() - TopB


MessageRequester("Resultat", "Gosub = " + Str(TopA) + Chr(10) + "Macro = " + Str(TopB) )

Inc:
A = A + 1
Return

Mais j'aimerais bien passer aux Macros, c'est peut être plus propre, plus lisble.
Neosis
Messages : 113
Inscription : dim. 24/févr./2008 20:11

Message par Neosis »

Effectivement la différence entre Macro et Gosub et faible ... j'ai fait le même test en rajoutant une Procédure... je savais que les procédures était plus longue à être appelé mais la d'après le test il faut 4 fois plus de temps a une procédure comparer à une macro ou Gosub, je pensais pas qu'il y avait un t-elle décalage... :?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

rien d'étonnant !!

une procédure pose les paramètres et l'adresses de retour sur la pile
(une procedure peut etre récursive)

au retour, il y a un dépilage de fait !!
donc c'est plus lent !!



un Gosub-----Return , c'est un Saut avec seulement l'adresse de retour qui est sauvegardé dans la pile , pas de paramètres , donc moins de trucs a empiler ou a dépiler :)

plus rapide, c'est carrement le Goto :)
Anonyme

Message par Anonyme »

une macro n'est pas comparable à une procedure , ou un gosub.
Si je ne me trompe pas , le précompilateur fait comme ca :


Code dans votre IDE favoris :

Code : Tout sélectionner

macro Test(A)
A+A+A+A
endmacro

B = 1
Test(B)
debug B 
Test(B)
Après le passage dans le précompilateur AVANT d'être compilé :

Code : Tout sélectionner

B = 1
B+B+B+B
debug B 
B+B+B+B
On constate donc que les macro sont des aides à la syntaxe , fort utile d'ailleurs. a ne pas confondre avec des procédures. :D
pas de saut & cie , c'est pourquoi c'est rapide d'ailleurs :D
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Message par Octavius »

OK, je vois, et en plus contrairement aux gosubs on peut utiliser des arguments. Ca peut être intéressant pour mettre au point un plot() ultra rapide! Dès que j'ai mis au point un bout de code je le poste ici!
Répondre