Comparing gen and Reaktor core level

Ernest's icon

There are obvious similarities. Before it was released, Native Instruments promised the core level would be an order of magnitude faster than primary modules--At least that was the theoretical prediction. However over time, empirical testing showed equivalent modules in Reaktor core to be definitely slower that prebuilt primary modules, and it only provided performance improvements for objects where there was no primary equivalent and design with primary-level modules was difficult.

Initial review doesn't make it obvious where gen is actually faster. We all hope the same isn't true for Max 6 as for Reaktor. All of us. Partly it must be a matter of choosing when to use gen....

For what applications exactly does gen provide a real performance improvement?

Andrew Benson's icon

Without getting into details, the most important difference is that Gen is actually generating and compiling source code from the Gen patcher. This means that a gen~ object functions within your patch like a compiled C object, although you can always open up the Gen patcher to alter the code. As you make changes, Gen recompiles the source code in place (assuming Auto-Compile is on). Using the codebox in Gen, you can also integrate text-based procedural code and expressions with visual programming.

Joshua Kit Clayton's icon

Hi Ernest,

Regarding performance:

For MSP, you will see large gains if you are using many simple objects in MSP to perform some task. So the same thing that you might be motivated to program an external object in C in order to get good performance. You won't see better performance than making your external object in C, but it will be quite close to that.

The basic rule of thumb, is that when you would be using a similar number of objects to accomplish the same task in MSP or Gen, the performance will be dramatically higher (e.g. 3-10x faster at 64 sample signal vector, and much more as the signal vector decreases).

In practice, you might be using only a handful of high level objects in MSP, in which case, you may not find any performance benefit to using Gen.

This latter case is probably similar to what you are describing--i.e. why in practice, most of the things you were doing in Reaktor didn't benefit from using Core. Typically, Reaktor programming is focused on high level objects, which are already compiled in C as a single unit. In MSP, there is much more of a low-level programming tradition, and therefore more of the former case, and I think for that reason, it will be of more benefit to MSP users.

For Jitter, if you use jit.gl.pix, you will see huge performance gains over using jit.op or other objects on the CPU. Similar to the above, however, you will not get much better performance than doing the equivalent in your own GLSL shader code.

We'll be working on the documentation and information surrounding Gen to make a variety of things clearer of when and why you might want to use Gen, but here's a short list:

General:
- You want to program visually at a low level while getting the performance of compiled C or GLSL code
- You want to use a concise text based expression language (codebox) rather than visual programming or coding in GLSL
- You want to avoid having to compile separate windows and macintosh versions (and in the future, 64-bit application binaries)

MSP:
- You want single sample feedback for things like building your own filters, FM synths, physical modeling, etc.)

Jitter:
- You want to be able to have a simple way to make use of the GPU for image processing both in visual and textual form

In the future:
- You want to program visually and get output as source code for use in other programs which you are working on as a developer

I hope this helps clarify a few things. We will be posting some examples which demonstrate some of the things I describe soon.

-Joshua

Joshua Kit Clayton's icon

Here's a really quick and dirty benchmarking example.

To demonstrate gen as faster than using many low level MSP operators:

benchmark-example-msp.maxpat ~47% cpu in minimixer
benchmark-example-gen.maxpat ~9% cpu in minimixer

So roughly 5x faster at 64 sample signal vector size. This is a pretty synthetic benchmark, but hopefully it illustrates the point of when and around what amount of improvements you might be able to achieve.

To demonstrate that gen~ is close to as fast as compiled C code, here's 512 biquads in Gen vs. MSP.

biquad-bench-msp.maxpat: ~19%
biquad-bench-gen.maxpat: ~22%

So it's only ~15% slower than the equivalent compiled C code for biquad~. This is a small network and a relatively simple MSP object, each with many instances. As the gen patcher and corresponding MSP object becomes more complex, the benefit should improve. And since the code is being generated, this can get better as we improve the system.

This should demonstrate that building something in gen~ is close to the as efficient as the equivalent compiled C code.

We can work on more examples of these sorts of things as time goes on, but hopefully this answers some of the questions you raise.

-Joshua

2742.genbench.zip
zip
Spip's icon

Thanks, it becomes to be clear for me, now.

Keep going, please. Really helpful.

Ernest's icon

Yes, thank you, those are really interesting answers.

On of the main problems for core-level performance in Reaktor is 'domain conversion' when transferring data between primary and core level. Is there a similar cost to signal movement in and out of core, that is, there are greater perofmrrance gains with lower I/O counts to gen?

How are gen~ objects disabled so they don't consume any CPU? How much overhead is there when a gen~ object is in some form of disabled state?

Architecturally the specifics are significant in many cases, for instance, whether to get performance improvement by building one multiple-ouput oscillator sharing one ramp, or whether to build one ramp in one gen~ unit, and disable different shapers on the ramp output for different oscillator waveforms.

I'm also curious about oversampling in gen, whether it requires separate objects, or whether oversampling is accomplished within the gen unit. Would you have any insight on that?

Joshua Kit Clayton's icon

Super brief answers:

- disabling objects is similar to other msp objects. Rare occurrence but possible, and not much overhead when the case.

- migrating data into gen has relatively minimal overhead.

- oversampling in gen is not present yet, but we will add it soon. For now wrap in poly~ for oversampling.

Veqtor's icon

What about wrapping gen inside pfft? Can we wrap pfft inside poly and gen inside pfft? =D

Also, what about some kind of way of making it easy to create kind of subpatches inside gen? This would be great considering that a lot of low level code easily gets really messy... Perhaps named busses like in core could be used to tidy up structures (not having loads of cables when routing one source to many destinations).

Also, when playing around with codebox I found that the for word was colorized, is this something you're planning on implementing?

Joshua Kit Clayton's icon

- pfft~? Yes. See spectral delay example.

- subpatchers? Not in first release, but soon.

- for loops? Also soon.

Julien Bayle's icon

thanks a lot to Joshua for his great answers.

One amazing thing (among others):

In the future:
- You want to program visually and get output as source code for use in other programs which you are working on as a developer

Currently writing a little paper here:
http://designthemedia.com/blog

More about gen~
- what do you mean by "concise text based expression language (codebox) " ?
- I often use JS instead of big max patch architecture tricky parts. can I put js inside gen~? does it make sense ? js isn't compiled. but could I expect improvements with gen~ ?

Joshua Kit Clayton's icon

- re: codebox and GenExpr: see the above PDF and let us know if you have specific questions.

- re: the js or any other non gen object for source generation: no. There will not be support for exporting the other code for any non-gen max objects; only what is inside the gen objects. That doesn't mean we couldn't have some js code output from the gen patcher, but then you would need to add your other js code to the output somehow yourself after export. It's still a while before that's ready, and I won't have time to answer lots of questions about functionality which doesn't yet exist. Thanks for your patience in the meantime.

Julien Bayle's icon

@jkc : you answered :) thx

Ernest's icon

Can gen~ function inside a poly~ object, and can it handle feedback? When I try making poly~ objects with feedback, there's no reported error, but I get no audio output. Others have reported similar experience.

Tj Shredder's icon

These performance tests are very interesting.
On my white Macbook (2GHz dual core) the benchmark-example-msp would kill Max 6 (cracles and 124% in the Mixer, Audio Status is blocked at 100%). I have to delete half of the patchers to get 60% CPU. The Gen version needs 25%, indeed impressive...
BUT! On Max 5 I can run the complete msp patch at 55% CPU...
Max 6 needs more than twice as much CPU compared to Max 5 with this patch...

With the biquad example, on the other hand, Max 5 and Max 6 need roughly the same 27%...

I am puzzled...

Julien Bayle's icon

@stefantiedje 32bits vs 64bits ..?

Graham Wakefield's icon

@Ernest: Yes, gen~ will function inside poly~, but the live auto-compile currently doesn't; you'll need to save the host poly~ patch to hear the updates.

Tj Shredder's icon

@Julien: can I change it?

Still the price for Max 6 seems at least 1000 Euro, as my patches which run fine in Max 5 do not run flawless anymore in Max 6 and I would need to buy a faster computer...
One patch doubles the CPU hit, the other is the same. They should both run with 64-bits as far as I know. It doesn't explain that difference in the CPU hit, as I run both Maxversions on a 64-bit processor. I would expect a performance hit, but anything which is more than 10% is not worth the gain in sound quality...
I'd rather keep the existing sound quality, than being forced to a new computer which would have lost a normally expected performance boost right out of the box...

Don't get me wrong, I love the new features and the overall advancement in the GUI, but the cost seem very high at the moment, and I can't overcome it with gen~ alone. I wonder how close we get with the performance problems with the final version. I know the elves are working on it...

Stefan

Julien Bayle's icon

@stefan: I guess they provide only one type of binary. I talked about the sound processing which came from 32 to 64 bits. But it is more a "feeling" because you wrote about a clearly " 2x more " something. I don't know.
As you wrote, it costs a lot even if it worth.
I own max5 too, it would cost me 450€ (upgrade with gen~)

Joshua Kit Clayton's icon

We've been making good progress with MSP performance in recent days and we will continue to improve in this area. The release version will be much faster than the beta version, especially on Macintosh where the difference in performance has been most noticeable.

Btw, where are you guys getting those prices above? Max is 399 USD and Gen is 100 USD for the full retail version. The max upgrade is 199 USD or 249 USD with gen. At current exchange rates, that's 178 EUR, not 450 EUR, Julien.

Julien Bayle's icon

@joshua
I'm sorry for the mistake.

Joshua Kit Clayton's icon

No problem. I was just surprised by these and wanted to clarify. I was especially surprised by Stefan's 1000 EUR figure. Maybe he accidentally typed an extra zero?

Julien Bayle's icon

:)

cannot wait for the RC!!

Ernest's icon

Thank you for your answers. Please could you illuminate a little how oversampling works in ~poly? At the output are the signals decimated to achieve lower sampling rate?

Elsehwere on the forums it's reported the minimum dalay is the vector size/ Is the same true in gen~, or is it possible to obtain a single-sample dealy in gen~?

Andrew Benson's icon

Tim or someone else may have to correct me here, but I believe poly~ uses a pretty advanced brickwall filter for resampling in Max 6.

Single-sample delay/feedback is one of the exciting use-cases for gen~ (use the 'history' object or 'delay @feedback 1'). This makes possible things like feedback FM, physical modeling synthesis, etc. that weren't possible using standard MSP objects before.

Ernest's icon

Wow, I just glanced at the 'msp quality' teaser, and it at least seems to indicate there are new options for oversampling in Max 6, and it seems at leadst fromn the screen display it's exactly the adio artifacts I was trying to remove in sinewaves is fixed with 64-bit audio, when I thought it was aliasing! Totally delighted )))

Tj Shredder's icon

@Joshua
My 1000 Euro are the difference between a faster Mac and what I could get for my old one. Had nothing to do with the upgrade price for Max at all...;-)
It wasn't that clear out of my post. Btw. I am willing to get a faster computer, just need to acquire the fundings somehow. I fell in love with the new Macbook Air, and it seems twice as fast as my old white Macbook. (Tested Max 5 with the same patches I throw at Max 6...)

Stefan

Alexis Baskind's icon

Hi all,

First, I would like to congratulate for the performance of standard MSP objects in Max6: as far as I tested, it's almost as effective as Max5, but in 64 bits. That's a big improvement with respect to the Max6 beta version.

Concerning gen~, I notice the same behavior than Stephan mentioned, i.e. it seems to be not effective at all on my machine, which is a Core 2 Duo 2.16 GHz from 2006 with Snow Leopard. The CPU is 64 bits but the EFI is 32 bits, so that SL boots in 32 bits, even if it can anyway run 64 bits applications.

Using benchmarks provided by Joshua, I get the following results:
. biquad-bench-msp.maxpat: 18% CPU, 35% on Activity Monitor
. biquad-bench-gen.maxpat: 77% CPU, 94% on Activity Monitor

My question is, are there any plans to optimize gen~ on 32bits-EFI machines, or is this hopeless ?

Cheers

Alexis

Joshua Kit Clayton's icon

Hi Alexis,

Thanks for bringing this up. I think the main issue is that some of the optimizations that we changed for standard MSP objects in the 6.0.0 release have not yet been applied to gen~. We will make those changes for 6.0.1, and you should see significant improvement, especially in patches with the history object.

My previous numbers above are from when those optimizations had not yet been applied to standard MSP objects.

However, there may be some processor discrepancies w/r/t performance, and we will continue to work on Max 6 optimization over the coming months.

Thanks,
Joshua

Roth's icon

I'm having the same problem Stephan and Alexis mentioned.

biquad-bench-msp.maxpat: ~19% CPU in MiniMIxer
biquad-bench-gen.maxpat: ~80& CPU in MIniMixer

MacBook Pro 2.2GHz Core2Duo (T7500) 4MB RAM running OS X 10.6.7

Ernest's icon

ok, I made the jump ) Max 6 is activated on Windows 7 64-bit, but it installed in 32-bit mode. On an i7 950 3.07 GHz, 6GB, with Creative THX TruStudio Pro audio:

Benchmark-example-gen: ~16% in minimixer (at least four times faster than on MacBook Pro 2.2GHz Core3Duo)

BUT

Benchamrk-example-msp:

...crashes without explanation....Tried MME, Directsound, and ASIO4ALL drivers, to no avail.

Joshua Kit Clayton's icon

@Ernest, are you running the release version or the beta version? I believe we fixed an issue in the release version with regards to stack overflow for that benchamrk-example-msp.

@Roth please see my message. I think we're addressing the major issues in 6.0.1 already

Ernest's icon

Thank you. I installed the new release which was shared October 26th, labled v1.0.0. The msp benchmrark file opens. As soon as I enable audio, however, it crashes immediately. I tried rebooting, restarting Max, turning overdrive on and off....

Roth's icon

@Joshua Yup, sounds cool. (I guess I was busy double checking that performance before hitting submit and your post snuck past me).

yoyo's icon

Hi,
I get the same question/problem as Ernest:
The question : on windows 7 64 bits, why max6 is installed on the Program Files x86 (the one for 32 bits programs)
The problem : I'm running Max version 6.0.0 on a i7-2630QM (4 cores) with windows 7 64bits, when I enable audio with the Benchamrk-example-msp patch, max crashes...
Thanks for your help

Andrew Pask's icon

Max installs into the 32 bit folder because it is a 32 bit binary. It processes audio in 64bits, but this does not make it a 64 bit application.

For those of your with crashing when turning audio on, does it persist after you delete your Preferences files?

On Windows 7 - quit max. Your preferences files are usually located somewhere like this

c:Users[Your username]AppDataRoamingCycling'74

Please note that "AppData" is an invisible folder and may need to be made viewable.

If you are still having problems after a restart please contact support

Cheers

Andrew

yoyo's icon

Hi!
Thanks Andrew for your answer.
After deleting my Preference Files (nothing to do with files preference, yeah?), I open Benchamrk-example-msp patch, enable audio and...max crashes. BUT, I then move the gen-bench folder somewhere in my max search path, enable the audio and...it works!
Can you explain me quickly why?
Thanks anyway for your help,
cheers,
A.

Andrew Pask's icon

No idea and I can't reproduce at all.

Please contact support with your information and we'll try and figure it out

-A

jpiringer's icon

so can we retrieve the gen~-generated code somehow? that would be really awesome for prototyping GLSL and audio-related c-code.

if yes, where do i find the code? wasn't very successful with the gen~-demo...

best
joerg

Julien Bayle's icon

@jpiringer: in this post, Joshua K.C. wrote:

In the future:
- You want to program visually and get output as source code for use in other programs which you are working on as a developer

You'll have that when those fantastic gurus will release this.
It will be amazing for all of us, dev.

jpiringer's icon

@Julien:
can't wait for this to happen!

thx
joerg

Ernest's icon

I'm very sad to report, I tried deleting the preferences folder. Max 6 wouldn't start until a reboot. Then I added the windows 7 desktop, including subfolders, to the Max search path. Then I opened the msp benchmark file from a desktop subfolder. Max 6 opened the patch, but when I started the audio, it crashed again.

Wesley Smith's icon

Ernest,
Please contact support to figure out what's going on.

Ernest's icon

Yes I will. The good news is, I was able to open a Max5 patch by adding its folder to the Max 6 search path. I couldn't open it if it was in a subfolder, but I could open patches in the specific folder declared in the Max6 search path.

Ernest's icon

Very happy. Max 6.05 is running with no problems. Trying oversampling now )