Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Measure performance of massive amount of scripts in scope of thousands/millions

Discussion in 'Scripting' started by qwertyuiop11110, Apr 13, 2020.

  1. qwertyuiop11110

    qwertyuiop11110

    Joined:
    Mar 16, 2020
    Posts:
    24
    I will have a script which will exist on thousands/millions of GameObjects. For obvious reasons it will start taxing player's computer. I have a couple theories to test in order to improve performance of massive amounts of the same script. However I don't know a way to measure it. What would be a way to directly and deterministically measure the amount of computation required for processing, a % in Resource Manager won't make it, and I don't know how reliant is the Profiler. Is there also a way to keep track of memory usage, and the function call delay? The script will contain async and IEnumerators and I would like to include those into the test as well.

    The important measurement factors to me are execution time, execution delay (if I create another instance, how long will it take to start a new script whilst the others are already taxing), average memory used (so I can shove off any megabytes needed), average processing tax (to see if I improved performance of my script).

    I'm looking for something reliable that will drop a specific number, I don't consider eye, guessing and estimating of good value. I'll repeat my tests a couple times.

    As a side question, is it possible to let GPU leverage some of the processing from the CPU? Reverse GPU instancing?
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,385
    What does this script do?

    If it's just a data container, it won't be that taxing (beyond the memory implications which are inherent to have millions of anything).

    But if say the script utilizes the 'Update' method, that means 'Update' is being called on all million objects every frame. This can be taxing.

    You should open the profiler (Window->Analysis->Profiler) and profile it. If you go into the 'hierarchy' view of it you can locate your scripts Update (or other methods) and see the cost of it relative to the total game cost:
    upload_2020-4-13_16-18-19.png

    Here's an example of my script 'CrosshairUI' and its 'LateUpdate'. It doesn't take up very much of my resources.

    More documentation on the profiler:
    https://docs.unity3d.com/Manual/Profiler.html

    Note... if you're trying to update millions of objects. This is usually where things like ECS comes in and allows for more efficient updates of that many objects.

    But like I said... if it's not doing stuff every update, the script isn't going to be that costly.

    This isn't to say other aspects may be... such as the rendering of those million objects. Things like batching help there. But without more information about what it is you're doing... I'm only speculating at this point.
     
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,748
    I'll just say, if you're even considering the possibility of millions of objects and aren't using ECS, you absolutely need to do that right now. No matter what other factors might be in play, you will never get acceptable performance for millions of Unity objects without using ECS.

    ECS will have things running in loops, and you can put your Profiler calls outside of those loops, which will give you more accurate overall performance numbers less dependent on Profiler's own overhead.
     
  4. qwertyuiop11110

    qwertyuiop11110

    Joined:
    Mar 16, 2020
    Posts:
    24
    Ooof, but that's the problem. Script will perform
    Update()
    processing, this is why it will be taxing.
    ECS? None of the result yield positive result, the first is Amazon ECS. There are other definitions but programming unrelated.

    Also, the profiler you mentioned. I have some scripts which do use Update, but I can't seem to find them in the ocean of Hierarchy and Raw Hierarchy. I do see other Updates, but none of the dropdowns contain mention of my script. Even when I type their full name in search bar. In your case it would be "CrosshairUI".

    Also, is there a way to hone it down to specific class? My solutions are based around multiple functions, async functions and IEnumertors and it will be an easy mistake for me to add them up incorrectly without knowing it. Profiler seems exactly like the tool that does exactly what I need, but I'd love it to single out specific class (and all its instances), can it be done? After minor examination I discovered that threads are segregated, that would be a solution, but then I found out that Unity doesn't support external separate threads.

    Edit: I see ECS, Entity Component System, but what are its drawbacks?
     
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,748
    qwertyuiop11110 and lordofduct like this.
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,385
    @StarManta gave you a link already. You're going to want to use it.

    You used the search bar and searched for the name of your script? It should come up. You have it set to hierarchy right?

    You should definitely read through the documentation of the profiler. Get familiar with it.

    Definitely read the documentation. I'm not the go to guy for specifics about it.

    Drawbacks are subjective. It's a different paradigm of looking at/solving your problems. It's geared towards managing large numbers of objects asynchronously. You should check it out... it's biggest benefits come in when managing millions of objects that need to be updated.
     
  7. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,748
    Pros: Insanely efficient.
    Cons: Harder to learn how to use, less pre-existing scripts available.

    If your situation is as described, though, there's honestly no point in discussing drawbacks. Running a million objects in Unity at any kind of acceptable framerate just flat out is not possible without using ECS (or implementing something on your own that would essentially be ECS).

    Do yourself a favor and run this experiment, to create the most basic theoretical possible "million objects running Update()" setup:
    1) Create a script with nothing but an empty Update() method:
    Code (csharp):
    1. public class EmptyUpdate : MonoBehaviour {
    2. void Update() { }
    3. }
    2) Create a second script which instantiates the above:
    Code (csharp):
    1. public int count = 1000000;
    2. void Start() {
    3. for (int i=0;i<count;i++) {
    4. GameObject go = new GameObject($"Object {i}");
    5. go.AddComponent<EmptyUpdate>();
    6. }
    7. }
    3) Run it

    Now, when I did this on my desktop (which is no slouch performance-wise) and ran it, it took almost a minute to execute Start() and then I briefly got about 3 frames over the next 5-10 seconds and then Unity crashed. That's with the script doing literally nothing.

    Anyway, the point of this is: downside or no downside, learn about ECS. It is the only possible way this can ever work.
     
  8. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,197
    It sounds curious to me that you didn't find your scripts in there. If the code executes in Update and an instance of that script existed in the frame you're looking at, it should show up under it's name when searching for it. (Everything else would be a bug)

    You could also wrap the code about whichs performance you are concerned in ProfilerMarker Begin/End calls to give it a name that would stand out more and is maybe similar across all the code related to the script, even if it isn't part of that class.

    To analyze the performance more in depth and in breadth than one frame at a time, you should also look into the Profile Analyzer. With that, you can e.g. run (A|B) experiments over multiple frames and then compare them too each other.
     
    Last edited: Apr 13, 2020
    qwertyuiop11110 likes this.
  9. qwertyuiop11110

    qwertyuiop11110

    Joined:
    Mar 16, 2020
    Posts:
    24
    Profile Analyzer provides all the tools I need and allows me to choose the class as well. So that's nice. Thank you :)
     
    MartinTilo likes this.
  10. qwertyuiop11110

    qwertyuiop11110

    Joined:
    Mar 16, 2020
    Posts:
    24
    I'm planning to undertake mission of translating my rather simple game from MonoBehaviour to ECS. However I am currently ignorant of underlying mechanics which leaves me with remaining question. Lets say I would make 100000 NPCs in ECS system, but I would leave camera management, networking and audio management in MonoBehaviour. Is this something that can be done?

    The largest problem for me is that I use a known networking library called Mirror. That library leverages a lot of networking jobs, however its written with classical MonoBehaviour technique. I asked almost same question there, however developers told me that they know little about ECS, so they couldn't help me.

    All that in a single question: If I create the most processing intensive scripts with ECS method (like AI for hundreds of thousands of soldiers) and keep my camera, sound and Mirror as MonoBehaviour, is that expected to work properly and as expected? This way I could keep the familiarity of MonoBehaviour's simpletonness on non-intensive scripts and selectively choose which intensive parts could be optimized with ECS.
     
    Last edited: Apr 14, 2020
  11. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,385
    Yeah, MonoBehaviours and ECS/jobs can co-exist in your project.
     
    qwertyuiop11110 likes this.
  12. qwertyuiop11110

    qwertyuiop11110

    Joined:
    Mar 16, 2020
    Posts:
    24
    Best News I've Heard In The Last Two Years To Be Quite Honest.
     
  13. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Just want to make a rather obvious point, that ECS is a far more efficient way of managing large numbers of objects, but it isn't magic. Your game is still limited by the resources of the hardware the game is running on. The AI for hundreds of thousands of units will still need to be designed extremely efficiently in order to work.

    Also, since this is a network game using Mirror, I certainly hope you don't have the crazy idea of just throwing a NetworkTransform on each of these hundreds of thousands of units and expecting that to work. It will certainly not. You'll have to design your own system for efficiently syncing that number of units. This might be a job for a lockstep approach instead of sending position updates.