Sunday, February 21, 2016

Exposing the Unity3D profiler window settings

Lately, I've been working on writing reverse engineering the internals of Unity's Profiler APIs and Window in hopes of doing my own viewer. This is part of the reason for the lack of new IL2CPP articles (although I do have some content I really want to cover, especially regarding virtual calls). Anyway, I want my own profile viewer.

A viewer that isn't limited to IMGUI patterns.

A viewer that isn't slow as hell (to the point of being unusable) when expanding CPU hierarchy nodes that are so many levels deep, especially in deep profiling (go jump off a bridge if you really think I have time to manage manual Sample traces, especially in code which is Unity agnostic, and the iteration times involved).

A viewer that can work on custom offline trace files. Which, maybe could provide ETL steps to spit out a .DTP version that is compatible with dotTrace. OK, so their formats don't appear to be open or documented, but you get the idea. One could even hack together a tool based off this Windows Heap profiler. Anything is possible when you have the raw data!

A viewer that is open source. Because one size does not fit all. If it did, I wouldn't be writing this blog post or reverse engineering the profiler!

Anyway, good progress is being made. I managed to get many of my LINQ utils working in the .NET framework used in Unity. Even uncovered some use cases that I didn't solve already in the process. It also helps that not all of the types used in the ProfilerWindow/APIs are marked internal. I expect to have some raw tools ready by early next month (probably in time for another round of profiling work at my day job).

But in the meantime, I'm serving appetizers!

Customizing the Profiler Window view

Yesterday, I happened to stumble across this programmer's tweet where he uses the PreferenceItem attribute to add custom Edit->Preferences options. Pretty cool! I then remembered how earlier I found (via ILSpy) that many of the Profiler Window's column's visibilities can be tuned by some EditorPrefs settings. Not long after, I was able to get the following settings working:


I can finally tune just how much BS is being displayed in the Profiler! Kind of a big deal, since I'm pretty sure part of the blame for slow down in the Profiler CPU Hierarchy is due to all the information it has to format into std::strings, which are then marshaled to C#, then processed in the window's IMGUI drawing code.

You can find the code for the editor here. You of course use it at your own risk. I will not be responsible for any strange states you may get your Profiler window into using it. On Windows, you could manually undo any craziness by regedit'ing the raw EditorPrefs key/values (just delete them).

It should be noted, however, that you can't dynamically add/remove columns with the Profiler window open. Before opening it, you must set your desired columns.

Also, a note about the code: I have a USE_SYSTEM_BITVECTOR macro. For public consumption, you'll want to keep this defined as it will cause the code to use the .NET BitVector32, instead of mine (which can do much more).

There's also some incomplete Chart prefs editors, in case anyone is that interested (I'm not, but did as much for completeness' sake).

Hope this helps others manage their...managed code profiling!


No comments:

Post a Comment