High "engine" CPU usage when using families.

  • I made a test involving many offscreen and inactive sprites. As expected it runs easily with low CPU readings. However, once I add these sprites to a family it causes a consistent rise in "engine" cpu usage per sprite, regardless of whether the sprite is doing anything warranting cpu usage or not.

    Adding the sprite to multiple families did not increase this "engine" cpu usage above what it already is.

    Is there a reason for this? As it stands I cannot create a large layout with many offscreen objects, if I also want to use families.

    I tested this in construct 2 also, as well as multiple versions of construct 3.

    Below is a link to the .capx :

    drive.google.com/file/d/11NUuzaMA4_5Yo0LrPvqsz4m4IJtra9zU/view?usp=sharing

    (add https:// to the front)

  • The engine does not do more work when you add a family to an instance, so I don't know why this would happen. FWIW the measurements C3 provides are very approximate and based on timers, which can make them unreliable. For me the C3 debugger measured 20% CPU time, but making more accurate measurements revealed it to be more like 7%, so it's at least not as bad as it shows.

  • Thanks for the quick reply!

    My experience with the debugger is that I maxed out the CPU at around 100K objects, whereafter I experienced declining fps.

    This would seem to indicate to me that the debugger is reliably showing the measurements, and that the problem is a real one, and not a misleading approximation.

    Is it a bug? As I said, it did the same thing in c2 also.

  • I just tested this as well. If the sprite is member of No families the CPU is 0% (Engine) even if there is 50000 in the layout. As soon as you start adding them to families The CPU usage goes up.

    I'm just guessing that somewhere in the background, there is something updating every tick with what family a sprite belong to. Maybe some SOL list or something? I have no other explanation for this. Something in the runtime that keeps track of what families a sprite belongs to?

    As you can't change members of family in runtime, I'm not sure why this is something that needs to be updated every time though (if it's that)?

    For large projects i think this can be critical, or even some mobile games, as you have a lot less CPU power to play with.

    Edit: Or if you take his project file. Run the debugger with the families. It shows for me 10% CPU usage.

    When you delete all the families. Run debugger again without any families in project, the CPU usage is 0.5% for the same amount of sprites in layout.

    This kind of boggles me, as I'm a heavy user of families in many of my projects.

  • As I said, the engine is designed to not do any extra work when you add objects to families, because obviously this would be a scalability issue. I stepped through the debugger with the given project and verified that it isn't doing any extra work, but the time taken do to the same work appears to increase anyway. Either I missed something, or there's a weird effect with the JIT compiler adjusting the optimisations as families are present, which wouldn't be surprising since there's a lot of accidental polymorphism in the C2 runtime. It might have to be something that we revise in the C3 runtime.

    Still, getting to 100,000 objects isn't too bad!

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Thanks for looking in to it.

    Yeah 100.000 static objects, is not that bad. But games are far from static, so losing a big portion of CPU time on something that isn't doing anything, or and is even invisible isn't really optimal just to use the family feature. Hopefully you can find and optimize this in future runtime updates.

    And as he said. As CPU time goes up Framerate drops.

    On a side note there seems to be no difference if you use 1 familiy or 15 families in the project. The increased CPU usage seems to depend on whether you're using any families at all. 0 families no CPU time increase.

    Edit: Or rather. 0 objects in families. No increase. the more instances that are in any family the CPU time increases. Anywhay, this is quite good to know, it's better to use families for low count objects like monsters etc, and not so much for building blocks and level sprites, that can get high numbers quickly.

  • Due to these recent findings I did some quick tests on an old mobile project:

    *Removed all static level objects from families. Instead bundled different objects in the same sprite by using Animations, and frames, and got a quite significant reduction to CPU time (Engine). (Mostly noticeable on mobile)

    Conclusion:

    * Don't place sprites with high object count in Families, as it will impact CPU usage.

    * Families most suitable for low object count sprites, like enemies and pickups, etc.

    * Reducing the amount of instances in a family will reduce CPU usage under "Engine".

    Maybe that would help some people with performance in large projects, and mobile projects on lower-mid range devices, until it has been looked at in a future update.

  • Ashley

    Just out of curiosity i ran the C3 performance test quad issue with and without Families as well.

    Without family I was getting about 185000 sprites.

    https://www.dropbox.com/s/q8ethv0ibpm0s ... y.png?dl=0

    With families i was getting 118000 sprites.

    https://www.dropbox.com/s/kr8s8h3nd4abr ... y.png?dl=0

    If most or all of your ingame sprites are included in one or several families, you could be looking at a quite significant performance drop. Resources that could be used to make the game better or have more fancy effects and gameplay mechanics, or just running smoother and better on less powerful devices.

    Show's quite a big decrease in performance when using a large number of instances in families. Families is such a nice and frequently used feature in most projects so I think it definitely deserves a bit of attention as it can be a major resource hog. Even for C2, and not as a C3 runtime exclusive update.

  • I tested it and indeed there's a difference.

    Without families the min CPU usage is 0.4% and the max is 1.6%. With even 1 family the min is 3.6, the max is 4.9%.

    It's 3 times more at the maximum CPU usage!

  • damn,

    pretty much every sprite in my game, bar the bullets and hud, are in a single family. Can be 100s at a time

    I will have a look tonight.

  • damn,

    pretty much every sprite in my game, bar the bullets and hud, are in a single family. Can be 100s at a time

    I will have a look tonight.

    Yeah i checked on of my projects as well, and got quite a nice performance boost by removing families. Every single Level sprite that was going to be Z-Ordered was in a family called Z-Order. 100's of instances.

    On my mid/low-end windows phone framerate jumped from 45-50 to constant 60fps now, and seemed to help a little bit with stuttering as well.

    I bundled all Level objects in the same sprite using animations and frames instead of using multiple objects and a family. I always wondered why my game was getting slower and slower as I added more static level sprites. Turns out it was because they were in families.

    I'm going to do the same for all my pickups, and other things as well that has a fairly high instance count.

  • What the hell?

    So Families are pretty much unusable if I'm developing for mobile? That's awful.

    But a big thank you to you guys for not just giving in and testing and insisting that there's something wrong with Families. Really good to know.

  • What the hell?

    So Families are pretty much unusable if I'm developing for mobile? That's awful.

    But a big thank you to you guys for not just giving in and testing and insisting that there's something wrong with Families. Really good to know. Makes you wonder if there really aren't even more things not working quite right hindering performance.

    I wouldn't say unusable, but it seems to be wise to keep an eye on how many instances that are members of a family, as it does seem to impact performance a bit. If the object count is low it doesn't have much impact, but if many of your sprites are in families there was a performance drop.

    Mostly noticeable on lower end devices or larger projects with a lot of sprites.

  • Just out of curiosity i ran the C3 performance test quad issue with and without Families as well.

    I can measure somewhere around a 30% hit when you add a family to the sprite being benchmarked. I would guess this is the polymorphism issue, which I've always suspected was an issue, but never found a way to isolate the overhead of - so this is an interesting test because you've found a way to highlight it!

    If I'm right, this is a somewhat complicated issue. It will probably be an on/off thing, i.e. either you get a fixed performance hit to the project, or you don't (I don't think it will get worse if you keep adding families, but maybe we should benchmark that too). It comes down to the way JavaScript JIT compilers work. At the moment the C2 runtime uses lots of different kinds of JavaScript "classes" (sometimes called object shapes in the engines). In this case there's a different class for a normal object type and a family, and in some parts of the engine both of these classes are used interchangeably in the same functions. JIT compilers optimise on what the code really does, and if you don't use families, all those functions use just one kind of class, and so the code is optimised for a single class (monomorphic code). As soon as you throw a family in to the mix, which is a different class, it has to change the optimisation to be able to handle multiple kinds of class (polymorphic code), which is slower since it involves checks for which kind of class is being used. There's a lot of this kind of thing in the C2 runtime, basically by accident. It's always been a goal of the C3 runtime to completely restructure all the code to remove all this polymorphism, which is why I mentioned "using monomorphic coding practices to reach peak performance in JIT compilers" in this blog post.

    The good news is... I've actually got enough of a working prototype of the C3 runtime to benchmark this already, and the C3 runtime does not have any performance impact when you add a family. So this is a nice confirmation that the new engine is indeed going in the right direction with its architecture, and should fix this problem throughout the engine. This could mean quite a big performance boost for large projects!

  • Thanks for the detailed explanation Ashley

    Sounds very promising that the new runtime is showing some nice improvements in this area. Very reassuring... Can't wait to see what else will get better with the new runtime

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)