Questions on the performance of different frameworks compared with stock VST (mda plugins) and native (FL Studio ) DAW plugins. | Getting Started with ASPiK | Forum

Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
Questions on the performance of different frameworks compared with stock VST (mda plugins) and native (FL Studio ) DAW plugins.
Avatar
Member
Members
June 30, 2021 - 4:35 pm
Member Since: June 16, 2021
Forum Posts: 43
sp_UserOfflineSmall Offline

G'day Everyone! 🙂

I have a perhaps pedantic sounding question. . . One that I'm sure if I were cleverer, I could answer it for myself. 😛 Why is it that some plugins, like the MDA VST example projects, seem to be insanely fast, even while doing what looks like a good bit of processing, and without use of code tricks and SIMD optimization; while projects I make in ASPIK or JUCE take more DSP time just idling with no processing or GUI at all. . . I'm not trying to pick on any plugins or frameworks. I really just want to know what these frameworks are doing in the background, even with no input audio.
//-------------------------------------------------------------

Experiment:

I've taken projects from ASPIK, JUCE, and the generic VST project generator, and compared them side by side in the DAW, which has a performance monitor that tells you how many microseconds it took to fill the output buffer, and displays this reading alongside the percentage of the total buffer period you used. I don't know if I can find a better profiler for plugins in development or not (visual studio? Vtune? -- how do I even use those? 0.0 ), but if my test is invalid and you have a better one, let me know! 🙂 In the end, the percentage of the total buffer period that your plugin takes to fill the output buffer, is sort of the only measurement you care about in an audio project, so seems valid enough to me to use that as a benchmark. (even though it changes with system load; it still shows the plugin performance relative to each other accurately, as long as you place them on separate tracks so none depends on the other's output -- or so I was told by my friends at Image Line. )

These "framework projects" were skeleton plugins. No processing code. Just generate the projects, build in release with the same compiler setup, and launch.

JUCE and ASPiK plugins take 30-90 microseconds to fill the bugger, doing absolutely nothing. (with ASPiK tending to be slower overall) Didn't matter whether the interfaces were open or not

MDA VST's (I used these because in my testing, these are nearly as fast as a skeleton VST project, and don't crash like an untouched VST will) like the Multi-band Dynamics, take 14-50 microseconds, even while processing audio and moving parameters. . .These plugins often outperform native offerings in my DAW. If only they sounded as good; I'd switch. 😛

And just for fun/reference, FL's native trim plugin, or their old 7 band parametric EQ, use 5-15 microseconds, even with the filters engaged. (that's not really fair though, as I know they use SIMD/SSE absolutely everywhere, from the mixer to the plugins, always processing interleaved streams where they can get away with it. And from what I understand, their GUI code overhead isn't visible from this performance monitor, because of how they make their plugins -- theoretically any plugin with the GUI on a separate thread shouldn't have GUI related overhead visible here. )

//---------------------------------------------------------------------------

So not the most scientific test. But it's consistent enough, and scales up to larger projects. So, again, my question is, why do even the empty juce and aspik plugins take so much more CPU time than the VST or native plugins? Where would all the overhead be coming from? I looked at the VST example plugins (mda plugins, specifically) and tried to work out how they compared to aspik and juce. . . And they are all quite different. (so much so, that honestly I have a hard time pointing to the bits they have in common. That might come with practice though. 🙂 )

In code (not that I'm completely sure what they're up to) the MDA plugins don't seem to have the same pre/post audio buffer processing that ASPIK does. They're very raw and to the point. No evidence of framework overhead. They just derive from MDA's base classes and setup a plugin that knows how many ins and outs it has, and exactly what it's going to do while it's alive, and it doesn't seem to try to handle anything else. . . I'm not even sure it updates it's parameters in a thread safe way -- but I'm not clever enough to work that out for sure. But what impresses me is, there are no special hacks or SSE code. It's chock full of branching and conditions. All 32 bit numbers. . . It's just blazing fast somehow. And I'd really love some help understanding why that is. It can't all be down to the GUI/lack thereof, can it?

Avatar
Admin
June 30, 2021 - 4:54 pm
Member Since: January 29, 2017
Forum Posts: 689
sp_UserOfflineSmall Offline

ASPiK has a plugin parameter smoothing operation that runs during idle and can impose a significant CPU hit, especially when you have a lot of GUI controls. This includes not only a built-in smoothing operation, but also includes the VST3 Sample Accurate smoothing option (see the VST3 SDK for sample accurate automation -- honestly I am thinking of getting rid of support for it, because no one seems to use it, or even know what it is).

The SynthLab-DM projects have a special configuration file that lets you disable the parameter smoothing altogether. That will then let you compare performance with and without it. I did find that Release builds are able to have vastly improved performance (85-90% speed up), and that on MacOS, the smoothing loop is practically transparent - which must have something to do with Xcode's handling of atomic variables, because my VST3 and AU Xcode plugins are always significantly faster in the idle loop. 

Now, there is a simple way to find out for ASPiK (I can't speak for JUCE) - use Visual Studio's profiling tools in debug mode and see for yourself. It will break down the processing into specific function calls, so you can find out where every fraction of a percent of CPU processing is being used. I used this extensively for SynthLab, to make the functions more efficient and also to track the idle-processing CPU (which was 99% in the aforementioned parameter smoothing operations).

You can answer your own question that way, and find out exactly what is going on. ASPiK does not link with any other DLLs or LIBs, so you have 100% of the code in each project right there in front of you to profile with! You can even see how the VST3 (or other plugin shell objects) are performing. There are lots of YouTube videos and C++ help sites on profiling with Visual Studio. The VS2017 profiling tools got a significant upgrade from VS2015.

Will 

Avatar
Member
Members
July 1, 2021 - 8:16 am
Member Since: June 16, 2021
Forum Posts: 43
sp_UserOfflineSmall Offline

W Pirkle said
ASPiK has a plugin parameter smoothing operation that runs during idle and can impose a significant CPU hit, especially when you have a lot of GUI controls. This includes not only a built-in smoothing operation, but also includes the VST3 Sample Accurate smoothing option (see the VST3 SDK for sample accurate automation -- honestly I am thinking of getting rid of support for it, because no one seems to use it, or even know what it is).

The SynthLab-DM projects have a special configuration file that lets you disable the parameter smoothing altogether. That will then let you compare performance with and without it. I did find that Release builds are able to have vastly improved performance (85-90% speed up), and that on MacOS, the smoothing loop is practically transparent - which must have something to do with Xcode's handling of atomic variables, because my VST3 and AU Xcode plugins are always significantly faster in the idle loop. 

You can answer your own question that way, and find out exactly what is going on. ASPiK does not link with any other DLLs or LIBs, so you have 100% of the code in each project right there in front of you to profile with! You can even see how the VST3 (or other plugin shell objects) are performing. There are lots of YouTube videos and C++ help sites on profiling with Visual Studio. The VS2017 profiling tools got a significant upgrade from VS2015.

Will   

Thanks for all that information, Will! One of my audio developer friends at Image Line thought it might have been because the idle blank plugin copies samples one by one from the input buffer to the output buffer, instead of handling the whole buffer in one go. (but they never saw code and it was a very casual conversation) I guess learning to use the VS profiler would tell me for sure, as you suggested. That sounds exciting, honestly. 🙂

Your comment about the OS X builds idling faster has me wondering: is that just clang/llvm being cleverer than msvc? I'm not about to swap out my compiler just yet, but eh. Something to think about. If one is demonstrably better at handling loops like these, that would make it pretty appealing for audio folks.

When you said you were considering dropping support for sample accurate automation smoothing, you just meant the VST implementation, and not all sample accurate automation or ASPIK's smoothing filter, right?

Avatar
Admin
July 1, 2021 - 12:04 pm
Member Since: January 29, 2017
Forum Posts: 689
sp_UserOfflineSmall Offline

Your friend is on the right track regarding audio copying. There are a couple of things you can also try when profiling, and I have a new RackAFX/ASPiK package that I am trying to have done by next week. 

First, you can remove all VST sample accurate parameter smoothing by removing/commenting out the line:

doSampleAccurateParameterUpdates( ) from the processAudioFrame( ) function. That will also disable the "normal" parameter smoothing, but will let you know it affects performance. 

Next, when I stated removing support, I was only talking about the VST3 Sample Accurate Automation stuff; right now, it is rolled in with the normal parameter smoothing code (and, if you have VST3 sample accurate updates, the normal parameter smoothing will NOT happen - so it is one of the other).

Finally, I setup ASPiK to use frame processing rather than buffer processing, with a note in the documentation about how to use buffer processing instead though no one seems to use it. For the new version of RackAFX and ASPiK, you can add audio sub-block processing, which eliminates sample copies and uses the normal buffer processing, but breaks that incoming buffer into smaller sub-blocks that are preferred for synth rendering. Processing with audio blocks massively improves performance (for a variety of reasons with synths and MIDI). 

I would suggest using the buffer processing to start (mentioned here):

http://aspikplugins.com/sdkdoc.....1b6a699e80

You can see that in the plugincore.h file, the processAudioBuffers( ) method is commented out.

1) Uncomment that function prototype

2) copy the PluginBase::processAudioBuffers(ProcessBufferInfo& processBufferInfo) function into PluginCore.cpp and change the class to PluginCore::processAudioBuffers...

This alone will override the frame processing.

3) now, look at the processAudioBuffers( ) function and you can see where I am breaking the buffers into frames for processing -- remove all of that code, along with the frame array stuff (inputFrame, outputFrame, etc...) which is all done purely to service the processAudioFrame( ) function. You now have access to the incoming and outgoing buffers directly, and you can do your processing on those buffers via pointers. For DAWs, these will be the raw (naked) pointers to the incoming and outgoing audio buffers. That will remove all audio copying and the function call stack pushing/popping. This will give you the best performance possible (note that the sample accurate automation stuff is not part of that function, so you would need to figure out how to add that for parameter smoothing. 

One thing to note - for SynthLab, there is the need to move around blocks of audio data (could be done with naked pointers, but I would face the wrath of the angry JUCE forum members) so I used memcpy( ) to copy 64-frame buffers - this is done between oscillator output and filter input, and then again from filter output to DCA input. During profiling, these bulk buffer copies were so far down the list of CPU hits, that they were less than 0.1% CPU and had no impact when compared to just a couple of tanh( ) functions used in other update methods. 

Lastly, at the heart of each PluginParameter object is an atomic floating point variable. I actually got this from the AU API (one of my former students worked at Apple in their audio division and was helpful with pointing out how to find that, and how it prevents half-baked data). During parameter smoothing, this atomic variable is accessed using the relaxed-memory specification, which should (in theory) be very close to the speed of a non-atomic variable access. I noticed that in Debug mode with VisualStudio, this access is very slow, but in Release configuration, it is nearly transparent. I also created a totally new version of PluginParameter, with a normal (non-atomic) floating point variable at its heart, and saw no difference in processing speed with Release builds, so I went back to the atomic version. 

Hope that helps you understand how things are working in ASPiK. If you have significant CPU findings or other information about speeding up performance while still keeping the parameter data accesses thread-safe, let me know and I will roll them into a new version of ASPiK. 

Will 

Avatar
Member
Members
July 1, 2021 - 11:36 pm
Member Since: June 16, 2021
Forum Posts: 43
sp_UserOfflineSmall Offline

W Pirkle said
Your friend is on the right track regarding audio copying. There are a couple of things you can also try when profiling, and I have a new RackAFX/ASPiK package that I am trying to have done by next week. . . .
.....
Hope that helps you understand how things are working in ASPiK. If you have significant CPU findings or other information about speeding up performance while still keeping the parameter data accesses thread-safe, let me know and I will roll them into a new version of ASPiK. 

Will   

WAOW!!! :D  I've never seen a VST only use 1-5 microseconds before! 😛 I honestly thought that was only possible with native plugins. And, unlike many other attempts, this one passes audio through it -- woot! (I've been struggling with this for a few hours; reading the buffer and frame processing code/data structures to see how to simply pass the input to the output. 😛 ) It ended up being simple, but you don't understand what you don't know. 😛 Reading about it is one thing; wrestling with it is another.

It's not all rosy though. I get an error MSB307 basically all the time, which I had hoped was because of the SDK being funky as you said in another post, but searching here for results suggests it may be a combination of things; either the validator is crashing because I haven't bothered checking or reporting my channel configuration, or it's not happy because I haven't implemented the midi queue in the buffer processing method and am no longer calling it from the frame processing method. The error disappears when I revert back to normal, so it's got to be one of those two things. . . No idea how the midi thing is going to work for the buffer processing method though. I haven't even thought about midi yet. I'll read the docs and peruse the book to see what I can come up with.

Additionally, the plugin in this configuration crashes when you try to unload it from a session, so something isn't happy there. Not sure what though. I thought it was the plugin not letting go of the buffers it was pointing to, so I uh. Embarassed. . . Well, tried storing whatever was in buffer.input[0] (or 1) in a float (which I did at least have the presence of mind to initialize to 0.0f as a class member.) and tossing whatever was being shoved in there to the output. " processBufferInfo.output[0] = &tmp; "EmbarassedEmbarassedEmbarassed . . . Yes, I see now that I was passing a memory address to the output buffer. . . No, I didn't realize that before. . . Yes, the noise was fantastic. . . And for what it's worth, no, I still don't know how to store the audio buffer and pass it back to the output buffer, or if that would have stopped it crashing when you unload the plugin. I'll crack open the synthlab projects and see how it's done tomorrow. Embarassed😛

I'm confused, but hopeful, given this glimpse of utter speed! It shows me that VSTs aren't at a disadvantage compared to native plugins! And I'm excited to actually know how to do buffer processing for other reasons. Supposedly it's necessary for SIMD type processing. (I know. 🙂 Cute, the guy that mistook the address of some data for the data it was pointing to, AND forgot he couldn't cram the whole input buffer into a single float, thinks he should worry about SIMD. 😛 )

Avatar
Member
Members
July 2, 2021 - 12:54 pm
Member Since: June 16, 2021
Forum Posts: 43
sp_UserOfflineSmall Offline

By the way, Will. I hope my verbose and often kind-of ineptitude laden replies aren't a burden. I'm just excited and enjoy sharing. 😛 (I kinda hoped somebody would find my stupidity funny. ) But It did occur to me this morning, that showing ineptitude and thinking out loud might come off as saying "I dunno what to do, show me how. Okay, now what? By the way, what's a compiler? " 😛 I don't mean to seem like I'm asking for solutions to every tiny problem. 🙂

I'll definitely have more questions, but those errors and crashes in the last post are things I can probably debug and figure out on my own. (and yes, I'm working on my overall understanding of the language so I don't put references in the audio path again. 🙂 I can read code, but apparently I can't write it. 😛 ) 

I'll say explicitly when I'm stumped in the future, and try to separate what I'm just thinking about out loud from what I actually wanted help with. 

The last thing I want from my time here is to be a nuisance to anyone and make working with me a chore. 🙂

Forum Timezone: America/New_York

Most Users Ever Online: 152

Currently Online:
7 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

Chaes: 56

Skyler: 48

StevieD: 46

Derek: 46

Frodson: 45

Peter: 43

TheSmile: 43

Nickolai: 43

clau_ste: 39

jeanlecode: 37

Member Stats:

Guest Posters: 1

Members: 768

Moderators: 1

Admins: 6

Forum Stats:

Groups: 13

Forums: 42

Topics: 842

Posts: 3347

Moderators: W Pirkle: 689