Page 3 sur 3

Publié : mar. 03/juin/2008 8:58
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

Publié : mar. 03/juin/2008 9:14
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")

Publié : mar. 03/juin/2008 10:18
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)

Publié : mar. 03/juin/2008 10:31
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 :)

Publié : mar. 03/juin/2008 10:47
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.

Publié : lun. 09/juin/2008 18:48
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.
@++

Publié : lun. 09/juin/2008 20:20
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 ?

Publié : lun. 09/juin/2008 20:24
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:

Publié : lun. 09/juin/2008 20:40
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.

Publié : lun. 09/juin/2008 20:51
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... :?

Publié : lun. 09/juin/2008 20:57
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 :)

Publié : lun. 09/juin/2008 21:57
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

Publié : mar. 10/juin/2008 1:09
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!