[BUG] Data structures/structs create HUGE frame drop!!

Answered

Comments

8 comments

  • YoYo QA Dept

    Hi Francisco,

    Thank you for your report. 

    The frame drop is due by the new Garbage Collector traversing a big number of data structures, disabling the Garbage Collector using gc_enable(false) fixes the problem. Additionally, performance is something we are continuously looking at improving so will take this issue into account when doing so. 

    I hope that answers your question, I'll mark this thread as Answered.

    Many thanks. 

    0
    Comment actions Permalink
  • Francisco Dias

    The garbage collector doesn't "collect" data structures (stacks/lists/maps) so that shouldn't have an impact on FPS.

    I also think Garbage collector should run on a separate thread.. to avoid this.

    1
    Comment actions Permalink
  • Core Tech

    The Garbage Collector will not collect data structures but it has to traverse them to find structs that are still alive, so they will contribute to the GC mark and sweep phase (which happens on the main thread). Mark and Sweep happens on the main thread (and has to stop the game while this happens). The Collect phase happens on a separate thread completely (which is the most expensive phase).

    But when you create a lot of data structures on one frame then the next GC mark and sweep will have to suddenly traverse a lot more to find dead or alive structs.

    Russell

    0
    Comment actions Permalink
  • Francisco Dias

    So you're saying eventually after some time the frame rate will recover?!

    Instead of the GC looking for structs inside variables wound't it be possible to make the structs when they need to be collected register themselves to the GC.
    This would avoid for the GC looking for them where they might not even exist?!
    and have each struct implement a reference count that increases everytime it is referenced:



    would something like this not work?! Russell Kay
    Sorry for my lack of knowledge... and for my questions :(

    0
    Comment actions Permalink
  • Core Tech

    Well the more data structures you have the more the GC has to sweep over, but the different generations will handle that so things that have been around for a while will be checked less often (so yes the framerate will recover).

    Unfortunately that will not work in a GC situation as you need to ensure that structures are not referencing each other so reference counting and registration will not work in many situations, as you can get deadlock and islands of references (where the whole island needs to be collected).

    Generational GC's are the way to go, but the will have an FPS impact for a period of time as structures move into different generations, that impact will decay away.

    Basically if you create lots of garbage then it will have an FPS impact (that will decay away), optimisation of how structs are created and used will be more important going forward.

    Russell

    0
    Comment actions Permalink
  • Francisco Dias

    I edited to post an alternative above:

    [ATERNATIVELY]

    1) store an additional reference to a struct in a hidden table (where the GC can look)...
    2) implement reference counter
    3) register for GC when the counter reaches 1 (the last reference would be the one from the hidden table)
    4) from time to time look through the table to find cyclic reference that could have been left behind.

    Cyclic references shoudn't be the more common ones.. they will happen but they are not the most common (in my opinion) so we could look at them separatly in a different time interval.

    Again, I'm not trying to teach anything.. if something I'm trying to learn so I'm sorry for my suggestions :)

    0
    Comment actions Permalink
  • Core Tech

    We have spent a long time looking at the best GC implementation for GMS and we tried lots of approaches (including the ones you mention) they all had problems and caused issues with structs being left behind and accumulating over time.

    Our current approach is the best one that we have found and a balance between cost and ease of use has to be struct.

    GC does not come for free.

    We will optimise over time as we review how it is being used, there are several performance tuning parameters that we can have and we have given you control over some of those (enable and disable the GC and perform full collections), these should offset some of the downsides.

    Russell

    1
    Comment actions Permalink
  • Francisco Dias

    Okay ;) thank you very much for the time spent explaining me this!
    It's cool this kind of interaction (I know this is not always possible.. but even for a small fraction of time, it's very cool)

    0
    Comment actions Permalink

Please sign in to leave a comment.