Sorry, no trace file at Downloads, but I’ll continue to figure out ![]()
The project where I want to use profiling is my drum machine Drumlabooh - https://psemiletov.github.io/drumlabooh/
@semiletov Cool project! Let’s continue to discuss on the github issue, I can help get you up and running there.
Hi Sudara,
Thanks also for this module! I’m getting into some GUI performance issues in a plugin I’m working on and this will shortcut so much work!
I’m including the module as a submodule in the CMakeLists.txt file (after linking all other JUCE modules)
add_subdirectory (../juce_external/melatonin_perfetto subprojects/melatonin_perfetto)
target_link_libraries(${PROJECT_NAME} PRIVATE Melatonin::Perfetto)
I’m finding that I can use Perfetto fine in my code, and any custom JUCE-style modules, but I run into compilation issues when I try and add the Melatonin module and TRACE_COMPONENT() macro to JUCE code.
Specifically, juce_Component.cpp in Component::paintComponentAndChildren(), as @stephenk did.
I get an error in Perfetto code (perfetto.h line 54451) about some unexpected token ‘struct’, but I don’t think this is where the real issue is.
All I’ve added to juce_gui_basics.h and juce_Component.cpp is
//gui basics module header
//...
#include <juce_graphics/juce_graphics.h>
#include <juce_data_structures/juce_data_structures.h>
#if PERFETTO
#include<melatonin_perfetto/melatonin_perfetto.h>
#endif
//...
//in juce_Component.cpp
//...
void Component::paintComponentAndChildren (Graphics& g)
{
#if PERFETTO
TRACE_COMPONENT();
#endif
auto clipBounds = g.getClipBounds();
//...
Commenting these lines out removes the error and so does removing PERFETTO=ON from the cmake args.
Have you run into this? I feel like I’m being gaslit by the C++ error codes ![]()
unexpected token ‘struct’
Heh, what a troll.
Specifically, juce_Component.cpp
If it’s your first time with Perfetto, I’d definitely recommend just sprinkling the TRACE_COMPONENT around in your own paint methods to get some success with the whole workflow first.
It’s not really “supported” to hack it into the actual JUCE code and expect it to work. That’s part of why I opened this feature request, because being able to officially hook into the paint cycle would make make recording timings and debugging performance WAY easier: FR: Callback or other mechanism for exposing Component debugging/timing
But you can get essentially the same data (with better naming) by peppering the macro in each of your paint calls…
Maybe someone else has ran into the issue? Or to go further off the beaten path you could try checking out an earlier commit, perhaps something in the recent bump to perfetto 41 made this impossible — if you do investigate, let me know if you get it working!
I’ve had a go “sprinkling” the macro around, and got some very pretty performance graphs, so it does work outside of JUCE code…
Shame that there’s no way to safely inject it into JUCE code though, I was hoping I could get a very detailed waterfall covering child components etc, something like what @stephenk got in their post above
I’ll take your advice and try an earlier commit, but I think I’ll have to settle for as much coverage in our own code as possible.
Thanks!
No luck in reverting. I went back to your v33.1 bump (41cc55b73c) and I got the same error.
I am using the VS2022 generator for the cmake builds, but I’ve tried with Ninja (CLion default) and get the same errors. Though they have less clutter…
If I find a solution, I’ll come back here but I’m not super hopeful
Good news! I got it compiling.
Wonky news, it was by commenting out that line causing the error…
::protozero::ConstChars interface() const { return at<2>().as_string(); }
inside the class NetworkPacketEvent_Decoder declaration. I tried looking into the function, it doesn’t look like it’s called anywhere in Perfetto or in the Melatonin module so ![]()
Nothing’s gone pop yet, and I’ve started benchmarking my UI without issues.
OK, so I’ve come back to this after a long while away and wanted to use Perfetto today.
I only previously ever used it in a standalone GUI App. But today I am trying to make it work in a VST3 plugin (Mac) and not having any luck.
I am launching the plugin attached to the AudioPluginHost (in the debugger). When the host appears, I place an instance of my plugin on the stage, double-click it to open the GUI, delete it, quite the APH - no dump file is created. It does not appear to run.
And yet, I just compiled my GUI App version and it does work, like it did previously.
Anything special needed to make this work inside a plugin?
EDIT: My bad. I had never put beginSession() and endSession() anywhere in the plugin code. I just added it to the AudioProcessor constructor and destructor and all is well.
Glad you got it working!
I’ll probably expand the docs like i did with blur and pamplejuce, so it’s useful to know what the speed bumps were.
Reviving this one, as I’ve been playing around with Perfetto for a bit, and ran into a weird issue.
I’ve added a bunch of TRACE_DSP()s and was recording a release build to look at some nice graphs, when I noticed that in the trace, some function that is called only once in my processBlock() would show up multiple times nested within the processBlock() trace. When I would remove the trace from that function, some other function that’s supposed to be called only once would multiply in a similar way.
Of course that’s weird and it severely limits trust in everything else I see in the traces. Debug builds are as expected.
Anyone seen similar issues? Why would optimization lead to slices being emitted multiple times? Feels kinda disturbing…
I don’t use Perfetto, but it isn’t necessarily wrong to see two of the same function name. The optimizing compiler might have multiple entry points to the same function, or different versions of the same function, in some cases. Does Perfetto allow you to inspect the function address and/or disassembly for the function which is shown multiple times?
Perfetto works by adding actual instrumentation code, so it’s not like a sampling profiler which just looks where execution is and tries to figure out a function symbol that matches. It basically adds code that explicitly emits events to be recorded when entering and leaving a function. Sudara conveniently put that stuff in some magic tiny macros. This should not be affected at all by optimization (= do whatever seems worthwhile, as long as it yields the same results in a single-threaded execution). At least that’s how I understand the whole thing works.
What I observed is basically the equivalent of having a single printf("foo\n") in a function and getting three "foo"s on stdout when running the function once in an optimized build. Again, as far as my understanding of the underlying mechanisms goes.
Just commenting to say I’ve read this and haven’t seen / heard of the problem before. I do profile quite a bit in Release.
The only issue I know of currently is one with using the macros inside lambdas, which should be fixed upstream shortly.
If you open an issue with some details on what your usage looks like I can take a deeper look. Would be useful to know if you are on latest version of the module, which compiler, etc.