Page 2 sur 4

Publié : lun. 11/sept./2006 18:38
par djes
Surtout que comme j'en ai déjà parlé il y a un moment, le code doit être aligné correctement si on veut avoir quelque chose de vraiment comparable...

Publié : lun. 11/sept./2006 20:14
par Dr. Dri
j'obtiens bien un meilleur score avec les pointeurs...
en moyenne : 3600ms pout les pointeurs et 3800 pour les poke

Dri

Publié : lun. 11/sept./2006 20:33
par Anonyme
Cela doit dépendre de l'architecture des processeurs, pas facile donc de faire de l'optimisation, il faudrait trouvé le type de proc, puis codé en fonction... :?

Publié : mar. 12/sept./2006 4:59
par Thyphoon
sur mon pc j'ai les Pokes qui gagne légèrement, et sur mon portable c'est l'inverse...comme quoi ... :lol:

Publié : mar. 12/sept./2006 8:03
par djes
On en a déjà parlé plusieurs fois sur les divers forums. Le fait d'accéder directement à la mémoire graphique avec le processeur est (en général) particulièrement lent. Il vaut mieux travailler soit avec les APIs (directx ou opengl), soit travailler en mémoire centrale, et envoyer le tout d'un coup (comme fait fred pour les opérations spéciales sur les sprites).

Publié : mar. 12/sept./2006 8:59
par Thyphoon
djes a écrit :On en a déjà parlé plusieurs fois sur les divers forums. Le fait d'accéder directement à la mémoire graphique avec le processeur est (en général) particulièrement lent. Il vaut mieux travailler soit avec les APIs (directx ou opengl), soit travailler en mémoire centrale, et envoyer le tout d'un coup (comme fait fred pour les opérations spéciales sur les sprites).
Le problème des API windows c'est que ce n'est pas compatible linux/MacOsX... :(

Publié : mar. 12/sept./2006 10:55
par djes
OpenGL est présent partout. Il n'y a qu'à modifier l'initialisation. Pour le reste, on peut se servir des macros. On peut aussi faire un subsystem... Voir celui-ci qui a l'air particulièrement prometteur : http://www.purebasic.fr/english/viewtop ... ht=directx

Publié : mar. 12/sept./2006 18:46
par djes
Quelques petits tests de remplissage ajoutés au code de CplBator. Pas eu le temps d'adapter l'opengl.

Code : Tout sélectionner

;Original code by CplBator

Structure DrawingInfoStruct
  Type.l
  Window.l
  DC.l
  ReleaseProcedure.l
  PixelBuffer.l
  Pitch.l
  Width.l
  Height.l
  Depth.l
  PixelFormat.l
  StopDirectAccess.l
  StartDirectAccess.l
EndStructure

Global FastImgOutputID.DrawingInfoStruct

;By Rescator
Procedure.l Ticks_HQ()
  Static maxfreq.q
  Protected t.q
  If maxfreq=0
    QueryPerformanceFrequency_(@maxfreq)
    maxfreq=maxfreq/1000
  EndIf
  QueryPerformanceCounter_(@t.q)
  ProcedureReturn t/maxfreq
EndProcedure
Procedure ___ReleaseFastImageOutput()
  If FastImgOutputID\DC:DeleteDC_(FastImgOutputID\DC):FastImgOutputID\DC=0:EndIf ; free the created memory DC
EndProcedure
Procedure ___StopDirectAccess()
  ProcedureReturn FastImgOutputID\DC
EndProcedure
Procedure ___StartDirectAccess()
  GetPixel_(FastImgOutputID\DC,0,0) ; make sure all GDI operations are finished
  ProcedureReturn FastImgOutputID\PixelBuffer
EndProcedure

; FastImageOutput() provides a faster pixel access for 32-,24- and 15 bit images(DIBSesctions).
; However, for now only plot(x,y,color) works faster. (point(x,y) seems to be not optimized for direct memory access at the moment. You can use the PointFast() command from the E2D Userlib to get a faster point command.)
Procedure FastImageOutput(Image)
  If GetObject_(ImageID(Image),SizeOf(DIBSECTION),ds.DIBSECTION)=0
    ProcedureReturn 0 ; no DIBSECTION
  EndIf

  FastImgOutputID\Type=7 ; allows direct memory access
  FastImgOutputID\ReleaseProcedure=@___ReleaseFastImageOutput()
  FastImgOutputID\PixelBuffer=ds\dsBm\bmBits+ds\dsBm\bmWidthBytes*(ds\dsBm\bmHeight-1) ;needed because the image if top down
  FastImgOutputID\Pitch=-ds\dsBm\bmWidthBytes
  FastImgOutputID\Width=ds\dsBm\bmWidth
  FastImgOutputID\Height=ds\dsBm\bmHeight
  FastImgOutputID\Depth=ds\dsBm\bmBitsPixel

  Select FastImgOutputID\Depth
    Case 32
      FastImgOutputID\PixelFormat=#PB_PixelFormat_32Bits_BGR
    Case 24
      FastImgOutputID\PixelFormat=#PB_PixelFormat_24Bits_BGR 
    Case 16
      FastImgOutputID\Depth=15
      FastImgOutputID\PixelFormat=#PB_PixelFormat_15Bits     
    Default
      ProcedureReturn 0 ; only 32-,24- and 15bit DIBSections are supported
  EndSelect

  MemDC=CreateCompatibleDC_(0)
  If MemDC=0:ProcedureReturn 0:EndIf ; the memory DC cannot be created
  SelectObject_(MemDC,ImageID(Image))
  FastImgOutputID\DC=MemDC

  FastImgOutputID\StopDirectAccess=@___StopDirectAccess()
  FastImgOutputID\StartDirectAccess=@___StartDirectAccess() 
  ProcedureReturn FastImgOutputID
EndProcedure


InitSprite()
OpenScreen(800,600,32,"PEEK AND POKE VS POINTER  :D ")

Structure Pixel
  Pixel.l
EndStructure : Global *Ptr.Pixel :  Global *Poke.l

Declare PointerDraw()
Declare PokeDraw()
Declare SpritePointerDraw()
Declare SpritePointerDrawFX()
Declare SpritePokeDraw()
Declare FastImg()

PTR.l = PointerDraw()
PKE.l = PokeDraw()
SPR.l = SpritePointerDraw()
SPX.l = SpritePointerDrawFX()
SPD.l = SpritePokeDraw()
FIM.l	=	FastImg()

CloseScreen()

MessageRequester("","POINTEUR = "+Str(PTR)+"ms"+Chr(10)+"POKE = "+Str(PKE)+"ms"+Chr(10)+"SPRPTR = "+Str(SPR)+"ms"+Chr(10)+"SPRPTRFX = "+Str(SPX)+"ms"+Chr(10)+"SPRPOKDR = "+Str(SPD)+"ms"+Chr(10)+"FASTIMG = "+Str(FIM)+"ms")

Procedure PointerDraw()
   Protected DBuffer.l,DBufferP.l,PixelFormat.l,Pbyte.l
   Protected TA.l,TB.l
   
   StartDrawing(ScreenOutput())
   DBuffer      = DrawingBuffer()
   DBufferP     = DrawingBufferPitch()
   PixelFormat  = DrawingBufferPixelFormat()
   StopDrawing()

   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
   diff.l			  = DBufferP-800*PixelFormat


   TA=Ticks_HQ()
   For i = 1 To 300 
      *Ptr = DBuffer
      For y = 0 To 600-1
         v.l=RGB(0,y*i,0)
         For x = 0 To 800-1
            *Ptr\Pixel = v
            *Ptr + PixelFormat
         Next
         *Ptr+diff
      Next
      FlipBuffers()
   Next i
   TB=Ticks_HQ()

   ProcedureReturn TB-TA

EndProcedure

Procedure PokeDraw()
   Protected DBuffer.l,DBufferP.l,PixelFormat.l,Pbyte.l
   Protected TA.l,TB.l
   
   StartDrawing(ScreenOutput())
   DBuffer      = DrawingBuffer()
   DBufferP     = DrawingBufferPitch()
   PixelFormat  = DrawingBufferPixelFormat()
   StopDrawing()
  
   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
   diff.l			  = DBufferP-800*PixelFormat

   TA=Ticks_HQ()
   For i = 1 To 300
      *Poke = DBuffer
      For y = 0 To 600-1
         v.l=RGB(y*i,0,0)
         For x = 0 To 800-1
            PokeL(*Poke,v)
            *Poke + PixelFormat
         Next
         *Poke+diff 
      Next
      FlipBuffers()
   Next i
   TB=Ticks_HQ()

   ProcedureReturn TB-TA
   
EndProcedure

Procedure SpritePointerDraw()
	Protected DBuffer.l,DBufferP.l,PixelFormat.l,Pbyte.l
	Protected TA.l,TB.l
	
	mem_spr.l=CreateSprite(#PB_Any,800,600,#PB_Sprite_Memory|#PB_Sprite_Alpha)
	StartDrawing(SpriteOutput(mem_spr))
	
	DBuffer      = DrawingBuffer()
	DBufferP     = DrawingBufferPitch()
	PixelFormat  = DrawingBufferPixelFormat()
	StopDrawing()

	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
  diff.l       = DBufferP-800*PixelFormat

	TA=Ticks_HQ()
	For i = 1 To 300 
		*Ptr = DBuffer
		For y = 0 To 600-1
			v.l=RGB(0,y*i,0)
			For x = 0 To 800-1
				*Ptr\Pixel = v
				*Ptr + PixelFormat
			Next
      *Ptr+diff
		Next
		DisplaySprite(mem_spr,0,0)
		FlipBuffers()
	Next i
	TB=Ticks_HQ()
	
	ProcedureReturn TB-TA
	
EndProcedure

Procedure SpritePointerDrawFX()
	Protected DBuffer.l,DBufferP.l,PixelFormat.l,Pbyte.l
	Protected TA.l,TB.l
	
	mem_spr.l=CreateSprite(#PB_Any,800,600,#PB_Sprite_Memory|#PB_Sprite_Alpha)
	StartDrawing(SpriteOutput(mem_spr))
	DBuffer      = DrawingBuffer()
	DBufferP     = DrawingBufferPitch()
	PixelFormat  = DrawingBufferPixelFormat()
	StopDrawing()
	
	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
  diff.l       = DBufferP-800*PixelFormat

	StartSpecialFX()
	TA=Ticks_HQ()
	For i = 1 To 300 
		*Ptr = DBuffer
		For y = 0 To 600-1
			v.l=RGB(0,0,y*i)
			For x = 0 To 800-1
				*Ptr\Pixel = v
				*Ptr + PixelFormat
			Next
      *Ptr+diff
		Next
		DisplaySprite(mem_spr,0,0)
		FlipBuffers()
	Next i
	TB=Ticks_HQ()
	StopSpecialFX()
	ProcedureReturn TB-TA
	
EndProcedure

Procedure SpritePokeDraw()
	Protected DBuffer.l,DBufferP.l,PixelFormat.l,Pbyte.l
	Protected TA.l,TB.l
	
	mem_spr.l=CreateSprite(#PB_Any,800,600,#PB_Sprite_Memory|#PB_Sprite_Alpha)
	StartDrawing(SpriteOutput(mem_spr))
	
	DBuffer      = DrawingBuffer()
	DBufferP     = DrawingBufferPitch()
	PixelFormat  = DrawingBufferPixelFormat()
	StopDrawing()
	
	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  
	diff.l       = DBufferP-800*PixelFormat

	TA=Ticks_HQ()
	For i = 1 To 300
		*Poke = DBuffer
		For y = 0 To 600-1
			v.l=RGB(y*i,0,0)
			For x = 0 To 800-1
				PokeL(*Poke,v)
				*Poke + PixelFormat
			Next
			*Poke+diff
		Next
		DisplaySprite(mem_spr,0,0)
		FlipBuffers()
	Next i
	TB=Ticks_HQ()
	
	ProcedureReturn TB-TA
	
EndProcedure

Procedure FastImg()

	CreateImage(1,800,600,32) ; only 32bit seems to be really faster...

	TA=Ticks_HQ()
	For i = 1 To 300
		StartDrawing(FastImageOutput(1)) ; replace this by ImageOutput(1)
		For y = 0 To 600-1
			v.l=RGB(y*i,0,0)
			For x = 0 To 800-1
				Plot(x,y,v)
			Next
		Next
		StopDrawing()
		StartDrawing(ScreenOutput())
		DrawImage(ImageID(1),0,0)
		StopDrawing()
		FlipBuffers()
	Next i
	TB=Ticks_HQ()

	StopDrawing()
	
	ProcedureReturn TB-TA
	
EndProcedure

Publié : mar. 12/sept./2006 19:17
par tonton
fait attention avec tes codes, djes, j ai fait une crise epilepsie. :roll:
bien failli me sectionner la langue ,moi!!

il a bien changé le "poke".., mon temps (heu..! pas si longtemps quant meme) le "poke" ecrivait directement sur la memoire.
maintenant, un "pokel" desassemblé donne ca:

PUSH dword [esp+36]
MOV eax,dword [p_Poke]
CALL PB_PokeL

ici, deux lecture memoire et un saut vers une procedure.
pas étonnant que que la vitesse du plot et du pokel, ce valent .

Publié : mar. 12/sept./2006 19:50
par Flype
ben, tu peux toujours programmer en asm si tu veux.

Publié : mar. 12/sept./2006 20:11
par djes
tonton a écrit :fait attention avec tes codes, djes, j ai fait une crise epilepsie. :roll:
bien failli me sectionner la langue ,moi!!

il a bien changé le "poke".., mon temps (heu..! pas si longtemps quant meme) le "poke" ecrivait directement sur la memoire.
maintenant, un "pokel" desassemblé donne ca:

PUSH dword [esp+36]
MOV eax,dword [p_Poke]
CALL PB_PokeL

ici, deux lecture memoire et un saut vers une procedure.
pas étonnant que que la vitesse du plot et du pokel, ce valent .
Oui je sais, j'en ai déjà parlé à Fred. Même chose pour les listes chainées, y'a des sauts partout! Là on a pris du code PB simple, sans assembleur.

Publié : jeu. 14/sept./2006 6:49
par SPH
Merci pour ce debat passionnant...

Faisons le point en posant cette question : finalement, l'affichage le plus rapide n'est il pas l'envoie de toute une banque de données dans la memoire video ?? (similaire aux pokes si je ne m'abuse...)

Maintenant, une question sur les sprites. En observant les images des meteorites du jeu INTRUDERS, on s'appercois qu'elles sont toutes en largeur et contiennent sur cette largeur toutes les images formant l'animation de chaque meteorite.
Alors, comme je sais qu'on peux faire un ClipSprite pour n'afficher qu'une partie de ce sprite, la tentation est grande de créer un seul sprite contenant toutes les images de l'anim de la meteorite et d'utiliser ClipSprite pour afficher seulement la bonne sequence de l'anim.
Mais est-ce preferable par rapport a la methode classique qui consiste a mettre l'anim sur plusieurs sprites ?????

Publié : jeu. 14/sept./2006 18:36
par Dr. Dri
bah je dirais qu'avec un seul fichier, tu as un seul sprite, donc une seule surface directx donc un seul acces pour afficher toutes tes météorites quels que soient leurs position dans l'animation. donc plus performant.

(c'est là tout l'intérêt du clipsprite...)

Dri

Publié : jeu. 21/sept./2006 7:44
par Thyphoon
des questions...(peut être idiotes ?! :roll: ) est ce que ça ne serait pas plus performant d'utiliser conjointement les pointeurs/pokes avec les fonctions startSpecialFX() et stopSpecialFx() ou en travaillant sur un sprite crééer avec l'option #PB_Sprite_Memory ?
J'ai fait des tests pour statSpecialFx() mais je n'ai qu'un ecran noir...et ça ne change rien au perf...je ne sais pas si je l'utilise bien. j'ai jammais bien compris ce qui se passait lorsqu'on utilisait ces fonctions...

Autre question quelqu'un ne pourrait il pas faire une fonction Poke en assembleur plus rapide puisqu'apparment, PB ne vas pas au plus simple ?

Je travaille toujours sur des effets 2d (lumière) ou je dois travailler au pixel...je cherche donc toujours a optimisé ! :P

Publié : jeu. 21/sept./2006 10:35
par erix14
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...