New Module: Profile your JUCE UI/dsp performance with Perfetto

:wave:

I’m a big fan of Perfetto for tracking down both UI and dsp issues in JUCE. I made it available as a JUCE module. Thanks to some CMake help from @benvining, it’s quite easy and flexible to get started with:

I wrote a bit about why Perfetto might be a better default choice than the normal profiler when it comes to investigating both dsp and painting issues in JUCE:

18 Likes

This is amazing work, thank you!

Profiling also won’t clearly answer questions such as how frequently something is called, or in what order things are called in. These are often critical pieces of information when performance tuning.

100%, I ran into this exact issue recently. Managed to solve it eventually, but I bet a tool like this would have found the problem straight away!

1 Like

Interesting approach. I think in Xcode you can get something pretty similar out of the box using signposts?

1 Like

Interesting, I actually haven’t seen signposts before, looks like a new-ish answer to trace tooling like Perfetto. I really like the Perfetto workflow (plus it’s cross platform / IDE independent) but I should check that out…

Looks very cool - I wish I could use it! But as I’m a Projucer user, not CMake, I can’t invest the time to switch over a bunch of projects to CMake to try it out. You mention Windows as the reason why it can’t be Projucer-compliant, but since I do most of my work on Mac, that wouldn’t be an issue. Will bookmark for future investigation.

Yeah, I was expecting Projucer to come up…

I’d be happy to work with you to get it up and running if you DM me here or on the discord. On macOS, there’s very little to the actual module itself, just some wrapper code around perfetto to make life nicer. I don’t use the Projucer (came to JUCE when cmake stuff was just starting), but I guess one should be able to download the perfetto sdk, and add it as a static library?..

Signposts are very old as far as I know. There are a few iterations of them but there’s a C api in kdebug_singpost.h that’s been around for ages. There’s been various replacements over the years.

This looks cool and I really like your way of sharing know how via those blog posts :slight_smile:

A few words on signposts though: We are using signposts in our macOS profiling workflow for exactly that. The nice thing is that it does not only work with the time profiler but also with other instruments. And also some other apps seem to emit signposts. I once had the case where one of our plugins was causing a processing overload warning in Pro Tools and I noticed that Pro Tools will emit a signpost when its audio engine detects an overload. Adding a few signposts to suspicious parts of the plugin code easily helped us reveal what function was accidentally called from the realtime thread to trigger that overload. I’ve added a handy scoped signpost wrapper class for stuff like that to our in-house codebase. I’d really recommend everyone having a look at them!

I once asked on Stackoverflow if there is a mechanism like that for other profilers and got an answer from an Intel engineer that VTune offers something similar. Never got to implement that though…

1 Like

Ahhh, makes sense!

Snap:

2 Likes

I used this in Vtune a few years back during development of a lockfree / fibers based task platform. They were phenomenally helpful. Being able to zoom way in and see the relative scales of different tasks across workers, etc. Haven’t had the need with JUCE work yet.

Wow, a lot of inspiring knowledge coming together here. I just had a look at our code, in contrast to @dave96 I used the group of functions documented here Apple Developer Documentation which allow to pass compile time static string literals as names instead of plain integer ids to better identify the signposts in the profiler.

@caustik that sounds promising. Will definitively revisit that topic at some timepoint and maybe finalise the cross-platform signpost wrapper :wink:

1 Like

Ah yes, I should probably update to that API…

Thanks to @dikadk13, we have some instructions for Projucer now and confirmed it works on macOS:

The state of Windows Projucer is unknown (required some fancy build settings in CMake), but if anyone is willing, I can help them get setup.

1 Like

That’s fantastic! I literally was right in the middle of writing you a DM saying I’d be willing to investigate it with you… and then went to your Git and saw that there were some new instructions for Projucer… and then this notification came in. Will try it soon!

1 Like

Feel free to DM if you run into any trouble!

So I managed to get this working, and did some test runs. One big problem I’m having is it’s almost impossible to select the individual events in the timeline.

(I wanted to check the drawing of some various LEDs I have that flash on pattern steps or tempo etc.)

So I put TRACE_COMPONENT in the LEDs’ paint() function. And all the little lines appear in Perfetto, but apparently they are too “short” (50 microseconds or less) and almost impossible to click on. Nothing happens.

I can draw a marquee around multiple items and select them that way, but not individual ones. Is there some trick to this?

Also, once I do manage to get one selected, is there some way to advance to the next event in the same line? The shortcuts description at perfetto say:

[ / ]
(with event selected)	Select next/previous slice that is connected by a flow.
If there are multiple flows,the one that is in focus (bold) is selected

Assuming they mean open and closed square brackets, this has no effect (on the mac at least).

I had the same problem when starting. Zoom in and navigate with the WSAD keys (like a video game). I’ll make that clearer in the writeup. I saw recently they had a popup or something now in the app top right to help explain that now…

zooooooooom

How are you getting it to display 3 different colored types of events stacked up in the JUCE Message Thread timeline?

The trace shows nested events in this way. Since components in JUCE are in a hierarchy, if you trace a component’s paint as well as its children (or other function calls or wrapped code chunks in the code path) the nesting will be visualized.