Search Home Members Contacts
About Us
Products
Downloads
Community
Support
Pages: [1]
  Print  
Author Topic: CreateRenderSurface slowdown - TV3D bug, or a DirectX thing?  (Read 950 times)
Lenn
Customers
Community Member
*****
Posts: 876

+/-


« on: September 23, 2008, 09:27:57 AM »

While finishing the optimisations on EvoGUI , getting ready for v1.0 in a few days, I've found one strange thing in my tests and careful measurements.

It seems that creating a render surface at the beginning of my app takes less time than after it is left running for a while. The conclusion is that the command
Surface = Scene.CreateRenderSurface
gets slower after each previous such command (followed correctly by Surface.Destroy) In other words, if you create and destroy the same surface many times, creating it again becomes slower.

I've made a little benchmarking app in VB, and you can test it for yourself. The code is included below.

I have originaly noticed the slowdown using the CreateAlphaRenderSurface command, but it's the same with CreateRenderSurface. On my test machine, core2duo 6750 @ 2.8 ghz , gforce 8800gt, the 3000 iterations in the test code below generate a 900% increase (9 times as slow) in the needed time to create and destroy a surface. 1000 iterations create a 250% slowdown.

Note however that I did perform more accurate tests separately and that Surface.Destroy() does not get slower, only Scene.CreateRenderSurface does.

So my question is: is this a TV thing or a DX thing? It could be TV if the surfaces get accumulating pointers/indexes and the new ones take increasingly longer to create because of the system needing to iterate through previously created ones if they are not removed when Surface.Destroy is used? I can imagine such an error being done by accident, happened to me. I didn't test surface creation in DirectX itself, but I may do that too.

If it's a TV thing, I'll post it as a bug. Thanks!


Code:
Imports MTV3D65


Public Class frmMain

    Inherits System.Windows.Forms.Form

    Public TV As TVEngine
    Public Scene As TVScene
    Public Inp As TVInputEngine

    Public bDoLoop As Boolean

    Public timer As System.Diagnostics.Stopwatch
    Public TempSurface As TVRenderSurface

    Declare Function GetFocus Lib "user32" () As Integer


#Region " Windows Form Designer generated code "
...
#End Region

    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim i As Integer
        Dim Time1, Time2 As Long

        TV = New TVEngine

        TV.SetDebugMode(True, True)
        TV.SetDebugFile(System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\debugfile.txt")

        TV.Init3DWindowed(Me.Handle, True)
        TV.GetViewport.SetAutoResize(True)

        Scene = New TVScene

        Inp = New TVInputEngine
        Inp.Initialize(True, True)

        timer = New System.Diagnostics.Stopwatch

        bDoLoop = True

        Me.Show()
        Me.Focus()



' Starts of test ----------------
        timer.Reset()
        timer.Start()
        For i = 0 To 10
            TempSurface = Scene.CreateRenderSurface(256, 256)
            TempSurface.Destroy()
        Next
        timer.Stop()
        Time1 = timer.ElapsedTicks

        For i = 0 To 3000
            TempSurface = Scene.CreateRenderSurface(256, 256)
            TempSurface.Destroy()
        Next

        timer.Reset()
        timer.Start()
        For i = 0 To 10
            TempSurface = Scene.CreateRenderSurface(256, 256)
            TempSurface.Destroy()
        Next
        timer.Stop()
        Time2 = timer.ElapsedTicks

        If Time2 > Time1 Then
            MsgBox("Time 2 is " + CStr(Time2 - Time1) + "ticks longer than Time1. This is a " + CStr(CInt((Time2 / Time1) * 100)) + " % increase!")
        Else
            MsgBox("On your machine, the increase does not seem to occur. Please tell this to the rest of the TV3D community!")
        End If

' End of test ----------------



        Do While bDoLoop
            If GetFocus = Me.Handle.ToInt32 Then
                TV.Clear(False)
                Scene.RenderAll(True)
                TV.RenderToScreen()
                If Inp.IsKeyPressed(MTV3D65.CONST_TV_KEY.TV_KEY_ESCAPE) Then bDoLoop = False
            Else
                System.Threading.Thread.Sleep(100)
            End If

            Application.DoEvents()
        Loop

        TV = Nothing

        End

    End Sub

    Private Sub frmMain_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        bDoLoop = False
    End Sub
End Class



Logged

TV3D 6.5 Community Docs - Read, use and please contribute!
TecnoBacon
Customers
Community Member
*****
Posts: 305


WWW
« Reply #1 on: September 23, 2008, 09:52:55 AM »

I tried the same thing and it appears to be garbage collection, since you are not forcing a GC you are causing the system to try and predict cleanup. I know, I know, GC causes a slowdown as well but you are hitting the system so fast that the GC container looks like it was run through a blender.

Logged

www.TecnoBacon.com - the other side of the Bacon family! 3D Development, Music and more.
Lenn
Customers
Community Member
*****
Posts: 876

+/-


« Reply #2 on: September 23, 2008, 09:58:06 AM »

Thanks for the input.
I thought about this, and waited for the app to clean up. I did other things that would normally cause it to collect the garbage, and it did collect but it was still slow afterwards. That was just one GC test which wasn't as technicaly accurate as the others, but I'm sort of confident it's not GC. You think I should spend more time and test if it is GC?
Logged

TV3D 6.5 Community Docs - Read, use and please contribute!
jviper
Community Member
*
Posts: 2126

Discipline in training


« Reply #3 on: September 23, 2008, 10:03:15 AM »

I'd say it would have to be some kind of memory management problem. After you call TempSurface.Destroy(), I think it is necessary for you to Set TempSurface = Nothing, otherwise TempSurface still holds whatever memory it was allocated.
Logged

JAbstract.....Don't just imagine, make it happen!
Lenn
Customers
Community Member
*****
Posts: 876

+/-


« Reply #4 on: September 23, 2008, 10:17:06 AM »

Good idea. But I already tried that too, that's how I coded things originaly. Made no difference, unfortunantely...

The only thing that comes to mind to single out memory management is to enable manual GC and test the specific speed on the CreateRenderSurface function with and without the = Nothing part, to make absolutely sure if that's it. I might just do that now, in fact.
Logged

TV3D 6.5 Community Docs - Read, use and please contribute!
ZaPPZion
Moderator
Community Member
*****
Posts: 554


« Reply #5 on: September 23, 2008, 10:19:29 AM »

yea, try calling GC.Collect()
that might help
Logged

Check out my website: www.bartkuipers.com
TecnoBacon
Customers
Community Member
*****
Posts: 305


WWW
« Reply #6 on: September 25, 2008, 10:02:50 AM »

If you can, check the memory allocs before and after, check each memory condition, free mem, alloc mem, etc....   I think that maybe TV is not releasing the memory quick enough. The GC has three stages of cleanup and the pointer list is most likely getting overloaded and fails to catch up. This causes the system to parse the list each access instead of retaining th last access address.
Logged

www.TecnoBacon.com - the other side of the Bacon family! 3D Development, Music and more.
Raine
Customers
Community Member
*****
Posts: 1212


« Reply #7 on: September 26, 2008, 02:58:28 AM »

http://msdn.microsoft.com/en-us/library/ms973837.aspx

http://blogs.msdn.com/ricom/archive/2003/12/02/40780.aspx

http://vineetgupta.spaces.live.com/blog/cns!8DE4BDC896BEE1AD!1104.entry?wa=wsignin1.0

« Last Edit: September 26, 2008, 03:00:45 AM by Raine » Logged

Lenn
Customers
Community Member
*****
Posts: 876

+/-


« Reply #8 on: October 01, 2008, 05:18:13 AM »

Ok, just to say that I have tried a lot of things using GC but none of them really worked. Even if the surfaces are created at a slower rate than the application would need it and left running for longer, the slowdown still happens and is solely and directly related to the number of times CreateRenderSurface is called. However, i haven't left the application running for more than 7 or 8 minutes so after that it might get cleaned up, but I doubt it. This is probably a memory management problem,and not a TV one , but I still have my doubts!

Thank you all for the input. Wink

I've solved the problem by eliminating surfaces as intermediaries for refreshing the gadgets. Now I've adjusted blending modes to work as I want them, and this is also an optimization of sorts. There are still many CreateRenderSurfaces called for some gadgets that would have to be rewritten in order to not use Surfaces, but I will see how it performs once we get it into practical usage and if it becomes a problem I will either research more into the subject or change the system (I already have plans).

If anyone finds any more info in the future, let me know.  Cool
Logged

TV3D 6.5 Community Docs - Read, use and please contribute!
Pages: [1]
  Print  
 
Jump to:  

Powered by SMF 1.1.3 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks