DSA faster in VidMem or in MainMem - Point() via DSA?

Advanced game related topics
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

DSA faster in VidMem or in MainMem - Point() via DSA?

Post by Kaeru Gaman »

Old Title
Drawing problem: mixed circle and plot slows down


we just discovered an issue I wasn't aware before:

mixing Plot and Circle in the same step of a loop can significantly slow down the execution.

this testcode was hacked together by three people:

Code: Select all

;   ========================================================================
   Enumeration
      #myWindowID
   EndEnumeration

   #myWindowWidth = 800 : #myWindowHeight = 600 : #myStarsQuantity =  150
   #myStarSpeedF  = 1.5 : #myStarSpeedM   =   1 : #myStarSpeedB    =  0.5

;   ========================================================================
   Structure ntStarType
      PositionX.f
      PositionY.f
   EndStructure

   Global Dim StarsLayerF.ntStarType(#myStarsQuantity)
   Global Dim StarsLayerM.ntStarType(#myStarsQuantity)
   Global Dim StarsLayerB.ntStarType(#myStarsQuantity)

   Global myEvent.l    = 0 : Global myKeyPressed.l = 0
   Global myCounterA.w = 0

;   ========================================================================
Procedure.f FpS2()
  Static Start_Zeit, Frames, SendFrames.f
  Zeit_akt = GetTickCount_()
  Frames + 1
  ZeitU = Zeit_akt - Start_Zeit
  If ZeitU
    SendFrames = Frames / ZeitU
  EndIf 
  If Zeit_akt >= Start_Zeit + 10000
    Start_Zeit = Zeit_akt
    Frames = 0
  EndIf
  ProcedureReturn SendFrames * 1000
EndProcedure
;   ========================================================================
   Procedure StarsCalculate()
      For myCounterA = 0 To #myStarsQuantity Step 1
         If (StarsLayerB(myCounterA)\PositionX - #myStarSpeedB) < 0
            StarsLayerB(myCounterA)\PositionX = #myWindowWidth -1
            StarsLayerB(myCounterA)\PositionY = Int(Random(#myWindowHeight -1))
         Else
            StarsLayerB(myCounterA)\PositionX = StarsLayerB(myCounterA)\PositionX - #myStarSpeedB
         EndIf
         
         If (StarsLayerM(myCounterA)\PositionX - #myStarSpeedM) < 0
            StarsLayerM(myCounterA)\PositionX = #myWindowWidth -1
            StarsLayerM(myCounterA)\PositionY = Int(Random(#myWindowHeight - 1))
         Else
            StarsLayerM(myCounterA)\PositionX = StarsLayerM(myCounterA)\PositionX - #myStarSpeedM
         EndIf
         
         If (StarsLayerF(myCounterA)\PositionX - #myStarSpeedF) < 0
            StarsLayerF(myCounterA)\PositionX = #myWindowWidth -1
            StarsLayerF(myCounterA)\PositionY = Int(Random(#myWindowHeight - 1))
         Else
            StarsLayerF(myCounterA)\PositionX = StarsLayerF(myCounterA)\PositionX - #myStarSpeedF
         EndIf
      Next myCounterA
   EndProcedure

   Procedure StarsDraw1()
      ClearScreen(RGB(0, 0, 0))
      StartDrawing(ScreenOutput())
         For myCounterA = 0 To #myStarsQuantity Step 1
            Plot(StarsLayerB(myCounterA)\PositionX, StarsLayerB(myCounterA)\PositionY, RGB(100, 100, 100))
            Plot(StarsLayerM(myCounterA)\PositionX, StarsLayerM(myCounterA)\PositionY, RGB(150, 150, 150))
            Plot(StarsLayerF(myCounterA)\PositionX, StarsLayerF(myCounterA)\PositionY, RGB(200, 200, 200))
         Next myCounterA
         DrawText(0, 0, StrF(FpS2()))
      StopDrawing()
      FlipBuffers()
   EndProcedure

  Procedure StarsDraw2()
     ClearScreen(RGB(0, 0, 0))
     StartDrawing(ScreenOutput())
        For myCounterA = 0 To #myStarsQuantity Step 1
           Circle(StarsLayerB(myCounterA)\PositionX, StarsLayerB(myCounterA)\PositionY, 1, RGB(100, 100, 100))
           Circle(StarsLayerM(myCounterA)\PositionX, StarsLayerM(myCounterA)\PositionY, 1, RGB(150, 150, 150))
           Circle(StarsLayerF(myCounterA)\PositionX, StarsLayerF(myCounterA)\PositionY, 2, RGB(200, 200, 200))
        Next myCounterA
        DrawText(0, 0, StrF(FpS2()))
     StopDrawing()
     FlipBuffers()
  EndProcedure

  Procedure StarsDraw3()
     ClearScreen(RGB(0, 0, 0))
     StartDrawing(ScreenOutput())
        For myCounterA = 0 To #myStarsQuantity Step 1
           Plot(StarsLayerB(myCounterA)\PositionX, StarsLayerB(myCounterA)\PositionY, RGB(100, 100, 100))
           Plot(StarsLayerM(myCounterA)\PositionX, StarsLayerM(myCounterA)\PositionY, RGB(150, 150, 150))
           Circle(StarsLayerF(myCounterA)\PositionX, StarsLayerF(myCounterA)\PositionY, 2, RGB(200, 200, 200))
        Next myCounterA
        DrawText(0, 0, StrF(FpS2()))
     StopDrawing()
     FlipBuffers()
  EndProcedure

   Procedure StarsDraw4()
      ClearScreen(RGB(0, 0, 0))
      StartDrawing(ScreenOutput())
         For myCounterA = 0 To #myStarsQuantity Step 1
            Plot(StarsLayerB(myCounterA)\PositionX, StarsLayerB(myCounterA)\PositionY, RGB(100, 100, 100))
            Plot(StarsLayerM(myCounterA)\PositionX, StarsLayerM(myCounterA)\PositionY, RGB(150, 150, 150))
            Circle(StarsLayerF(myCounterA)\PositionX, StarsLayerF(myCounterA)\PositionY, 2, RGB(200, 200, 200))
         Next myCounterA
         DrawText(0, 0, StrF(FpS2()))
      StopDrawing()
      FlipBuffers()
   EndProcedure

  Procedure StarsDraw5()
     ClearScreen(RGB(0, 0, 0))
     StartDrawing(ScreenOutput())
        For myCounterA = 0 To #myStarsQuantity Step 1
            Plot(StarsLayerB(myCounterA)\PositionX, StarsLayerB(myCounterA)\PositionY, RGB(100, 100, 100))
           Circle(StarsLayerM(myCounterA)\PositionX, StarsLayerM(myCounterA)\PositionY, 1, RGB(150, 150, 150))
           Circle(StarsLayerF(myCounterA)\PositionX, StarsLayerF(myCounterA)\PositionY, 2, RGB(200, 200, 200))
        Next myCounterA
        DrawText(0, 0, StrF(FpS2()))
     StopDrawing()
     FlipBuffers()
  EndProcedure


;   ========================================================================
   If Not InitSprite()
      MessageRequester("Sternenfeld", "Es ist ein DirectX Fehler aufgetreten - InitSprite( )", #PB_MessageRequester_Ok ) : End
   EndIf

   If Not InitKeyboard()
      MessageRequester("Sternenfeld", "Es ist ein DirectX Fehler aufgetreten - InitKeyboard( )", #PB_MessageRequester_Ok ) : End
   EndIf

   If Not OpenWindow(#myWindowID, 0, 0, #myWindowWidth, #myWindowHeight, "Sternenfeld", #PB_Window_ScreenCentered|#PB_Window_BorderLess)
      MessageRequester("Sternenfeld", "Es ist ein Fehler aufgetreten - OpenWindow( )", #PB_MessageRequester_Ok ) : End
   EndIf

   If Not OpenWindowedScreen(WindowID(#myWindowID), 0, 0, #myWindowWidth, #myWindowHeight, 0, 0, 0)
      MessageRequester("Sternenfeld", "Es ist ein Fehler aufgetreten - OpenWindowedScreen( )", #PB_MessageRequester_Ok ) : End
   EndIf

;   ========================================================================
   For myCounterA = 0 To #myStarsQuantity Step 1
      StarsLayerB(myCounterA)\PositionX = Int(Random(#myWindowWidth - 1))
      StarsLayerB(myCounterA)\PositionY = Int(Random(#myWindowHeight - 1))

      StarsLayerM(myCounterA)\PositionX = Int(Random(#myWindowWidth -1))
      StarsLayerM(myCounterA)\PositionY = Int(Random(#myWindowHeight - 1))

      StarsLayerF(myCounterA)\PositionX = Int(Random(#myWindowWidth -1))
      StarsLayerF(myCounterA)\PositionY = Int(Random(#myWindowHeight -1))
   Next myCounterA

;   ========================================================================
   SetFrameRate(1000)
;   ========================================================================

   Repeat
      ;myEvent = WindowEvent()
      ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Escape)
         myKeyPressed = #PB_Key_Escape
      EndIf
      StarsCalculate()
      StarsDraw1()
   Until myKeyPressed = #PB_Key_Escape

;   ========================================================================
   End

;   ========================================================================
change the Number of the Draw routine in the mainloop.

on a CRT the result was 240, 80, 40, 40, 40 FpS, on a TFT it was 120, 60, 4, 4, 4

4 FpS when altering circle and plot in the same loopstep, really strange.


could others please test and confirm, disprove or explain?
Last edited by Kaeru Gaman on Thu Oct 30, 2008 3:41 pm, edited 1 time in total.
oh... and have a nice day.
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Confirmed and I have no idea why it is happening, I tried changing the order of circle and plot in routine 3 but it didn't help. I'll keep trying.
Anonymous

Post by Anonymous »

I confirm too , it's very strange :?
Fred
Administrator
Administrator
Posts: 18263
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

It's becasue Plot(x,y, color) is accelerated fro direct surafce access, so there is a context switch (from DC to raw surface access). As circle is not, it siwtches again. and again. Better use Plot(x,y) instead as it uses DC standard plot function.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

ah! thanks for that explanation.
I already suspected there was something like a DC change,
but I wondered why because both accesses should aim the same DC.
now that is clear.

so the solution is, either use Plot without color when needing to mix commands up,
or do all plots devided from the other drawings.

this opens another question...
if I have, say, a thousand plots with the same color...
are they faster via Plot(x,y,color), meaning DSA, or with Plot(x,y), meaning DC...?
oh... and have a nice day.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

Reading FRED I would say Plot(x,y)... if you had a great many... then change colors and do the next batch!

:shock: You hacked three people to make that source code... I usually just sacrifice a chicken and dance naked around in my backyard! :shock: :D
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

"by" not "out of"... seems here in Gerany we speak better English than in Texas... ;)

... are you practicing Woodoo?

Reading FRED I would say Plot(x,y)...
well, no, this was not implementet in this answer.

I would read it the other way round:
"Plot(x,y, color) is accelerated for direct surafce access"
thus it is faster than "Plot(x,y) instead ... uses DC standard plot function"
oh... and have a nice day.
User avatar
Demivec
Addict
Addict
Posts: 4270
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

Kaeru Gaman wrote:
Reading FRED I would say Plot(x,y)...
well, no, this was not implementet in this answer.

I would read it the other way round:
"Plot(x,y, color) is accelerated for direct surafce access"
thus it is faster than "Plot(x,y) instead ... uses DC standard plot function"
Actually, if you are mixing in Circle() you would be better off, in your loop examples to use Plot(x,y) instead so that it doesn't have to change DC's .

For instance, this is about twice as fast after you make these changes to keep the DC's from being flipped:

Code: Select all

Procedure StarsDraw5()
  ClearScreen(RGB(0, 0, 0))
  StartDrawing(ScreenOutput())
    FrontColor(RGB(100, 100, 100)) ;added
    For myCounterA = 0 To #myStarsQuantity Step 1
      ;Plot(StarsLayerB(myCounterA)\PositionX, StarsLayerB(myCounterA)\PositionY, RGB(100, 100, 100))
      Plot(StarsLayerB(myCounterA)\PositionX, StarsLayerB(myCounterA)\PositionY)
      Circle(StarsLayerM(myCounterA)\PositionX, StarsLayerM(myCounterA)\PositionY, 1, RGB(150, 150, 150))
      Circle(StarsLayerF(myCounterA)\PositionX, StarsLayerF(myCounterA)\PositionY, 2, RGB(200, 200, 200))
    Next myCounterA
    DrawText(0, 0, StrF(FpS2()))
  StopDrawing()
  FlipBuffers()
EndProcedure
Last edited by Demivec on Fri Sep 05, 2008 8:34 pm, edited 2 times in total.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

Demivec wrote:Actually, if you are mixing in Circle() you would be better off, in your loop examples to use Plot(x,y) instead so that it doesn't have to change DC's .
this was the starting question that was already answered by Fred.


now I'm talking about
Kaeru Gaman wrote:if I have, say, a thousand plots with the same color...
are they faster via Plot(x,y,color), meaning DSA, or with Plot(x,y), meaning DC...?
oh... and have a nice day.
User avatar
Demivec
Addict
Addict
Posts: 4270
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

Kaeru Gaman wrote:
Demivec wrote:Actually, if you are mixing in Circle() you would be better off, in your loop examples to use Plot(x,y) instead so that it doesn't have to change DC's .
this was the starting question that was already answered by Fred.


now I'm talking about
Kaeru Gaman wrote:if I have, say, a thousand plots with the same color...
are they faster via Plot(x,y,color), meaning DSA, or with Plot(x,y), meaning DC...?
You are correct if you are only plotting, to use Plot(x,y,color) for faster results. I thought the conversation was continuing the idea of mixing circles and plots still. My appologies for misconstruing the ideas.

I get a a difference, in the loops you used of 230 fps with Plot(x,y,color) to 214fps with Plot(x,y).
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

hey, no problem...
I also happen sometimes not to read each and every sentence in a thread. ;)
thanks for your support in so much cases, anyways. :)
oh... and have a nice day.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

are you practicing Woodoo?
No I just hate chickens and like to dance naked... :wink: It does, however, explain my coding style!

DemiVec that is a nice example!
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

Demivec wrote:I get a a difference, in the loops you used of 230 fps with Plot(x,y,color) to 214fps with Plot(x,y).
since I do not trust not specialized tests, I wrote one.
I get a really significant difference:
DC: 9718ms DSA: 63ms

...hope I didn't make a mistake...

run with debugger disabled.

Code: Select all

InitSprite()
InitKeyboard()
OpenWindow(0,0,0,800,600,"test")
OpenWindowedScreen(WindowID(0),0,0,800,600,0,0,0)
Define n, x, y, timer1, timer2

; clear the eventqueue to minimize errors
While WindowEvent() : Wend
Delay(100)

FlipBuffers()

StartDrawing(ScreenOutput())
timer1 = ElapsedMilliseconds()
For n=0 To 9
  FrontColor($FFFFFF)
  For y = 0 To 599
    For x = 0 To 799
      Plot(x,y)
    Next
  Next
Next
timer1 = ElapsedMilliseconds()-timer1
StopDrawing()

FlipBuffers()

StartDrawing(ScreenOutput())
timer2 = ElapsedMilliseconds()
For n=0 To 9
  For y = 0 To 599
    For x = 0 To 799
      Plot(x,y,$FFFFFF)
    Next
  Next
Next
timer2 = ElapsedMilliseconds()-timer2
StopDrawing()

out$ = "Testet 4,800,000 Plots" + #CRLF$
out$ + "DC: "+Str(timer1)+"ms" +#CRLF$
out$ + "DSA: "+Str(timer2)+"ms"

CloseWindow(0)

MessageRequester("Result",out$)
oh... and have a nice day.
User avatar
Demivec
Addict
Addict
Posts: 4270
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

Kaeru Gaman wrote:
Demivec wrote:I get a a difference, in the loops you used of 230 fps with Plot(x,y,color) to 214fps with Plot(x,y).
since I do not trust not specialized tests, I wrote one.
I get a really significant difference:
DC: 9718ms DSA: 63ms

...hope I didn't make a mistake...
I got DC: 6047ms DSA: 47ms ( I must have a slower machine...)
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

yours is faster... it's duration time.
oh... and have a nice day.
Post Reply