How to configure Max for multi core CPU use?

Jonatan Ewald's icon

Jonatan Ewald

3月 14 2017 | 9:21 午後

Hi,
I know that there are some threads touching upon this, but none that I found seems to give too many answers so I will give it another try;
How can I arrange my patches so that the CPU load gets spread as evenly as possible over all CPU cores in my system?
I saw that the poly~ object seems to have something for this. Does that mean that I can run each voice on a separate CPU core?
If I have more cores than voices can I then still spread the load so that one voice uses 2 cores?
How many cores does Max support?
Can I get a 10 core intel i7 CPU and use the full processing power in Max or maybe even a Xeon with 22 cores?
What are the limitations, is it possible to setup so that Max uses all the available processing power dynamically and if not are there any workarounds or smart ways to program so that all CPU cores gets used?

Regards,
Jonatan

bt.soundmaker's icon

bt.soundmaker

3月 15 2017 | 5:57 午後

the poly~ tutorials talks about multi threading somewhere I think?

Jonatan Ewald's icon

Jonatan Ewald

3月 16 2017 | 9:26 午後

Hi,

Thanks for the reply.
I guess I need to read up on how poly works in more detail then.

Is it possible to run multiple instances of different subpatches in poly~ and in that way use multiple threads for different processing, or is it mainly used for duplicating one task such as adding additional voices of the same sound?

Is there any kind of generic setup of Max so it utilizes the available processing power in the most efficient way or is poly~ the only way to go?

Is there any way of managing the CPU cores so that I can control what core is used for what?
The last item is not really important to me other than that I see a lot of time only one or two cores are actually used while the others run on idle and it would then be nice to be able to force some processes to one of the cores that are hardly ever used.

bt.soundmaker's icon

bt.soundmaker

3月 20 2017 | 12:57 午後

Threading in Max, video from cycling74!
https://youtu.be/7n-sl687tkI


Jonatan Ewald's icon

Jonatan Ewald

3月 20 2017 | 11:22 午後

Thanks Ben!
That was really helpful!
But that video basically stated that there are 3 threads (main, scheduler, audio).
If I have a processor with 8 cores, how do I then spread my calculations over all the cores in an efficient way for a real-time response?

Mark Norman's icon

Mark Norman

9月 14 2019 | 4:13 午後

Jonathan (or anyone else for that matter) ... did you ever find out if you can take full advantage of all cores with Max?

Ernest's icon

Ernest

9月 15 2019 | 1:01 午後

Each instance of a poly~ object is spread across all the available cores.

Pedro Santos's icon

Pedro Santos

9月 15 2019 | 7:43 午後

For audio, each top level Max patch is processed on a different thread.
If you have SIAI (Scheduler in Audio Interrupt) turned on, then regular events will also have a separate thread.

Steffen Günther's icon

Steffen Günther

7月 07 2020 | 3:25 午後

@Pedro Santos
As discussed in the threading video B.T. shared:
a patch has three threads (main, scheduler and audio).
BUT threads are not CPU cores. So there are a few questions arising in my head:

1. Do I understand it correctly that the three threads of one patch are running on one core? (are there exceptions?)
2. Is each top level Max patch running on a different core? ...or else what do you actually mean by "processed on a different thread" Pedro?

One observation: If you export multiple standalone applications from Max and run them simultaneously they are processed on different CPU cores. If those applications communicate via UDP-send/-receive this could be a workaround to distribute the work load to different cores (that I would prefer not to use).

Does anyone have some deeper insight in how to distribute evenly on all CPU cores? Poly~ is not a solution for everything...

toothpaste's icon

toothpaste

8月 28 2020 | 7:55 午前

it's sad (and annoying) that this very important question has been hanging here for the past 3 years without an answer

Roman Thilenius's icon

Roman Thilenius

8月 28 2020 | 10:29 午前


"If you export multiple standalone applications from Max and run them simultaneously they are processed on different CPU cores "

yes, or like pedro pointed out above, seperate patcher windows in the same runtime.

so even in a standalone later you could open 3 invisible, special patchers via pcontrol and do some s/r there for running the reverbs or vst plug-ins or whatever.

this is not elegant, but still better than using poly~.

toothpaste's icon

toothpaste

8月 28 2020 | 4:28 午後

How about management of threads PER patcher window? Say I have an audiovisual patch which includes a ton of msp, jitter and max operations (not to mention drawing of the number boxes etc. GUI calculations(?))

Are all these calculations handled by one core alone? I'd be more than happy if someone from the staff could answer this question.

Jean-Francois Charles's icon

Jean-Francois Charles

8月 28 2020 | 5:09 午後

Toothpaste, the standard solution if you have, say, two large patches, is to launch Max twice. It will be allocated to different cores by the OS.
It's basically what Roman and others said, except you don't have to make a Standalone. That will save you headaches, and memory space.
On Mac, to launch an app a second time, you can use the Terminal and use the -n flag:
open -n /Applications/Max\ 8.app

toothpaste's icon

toothpaste

8月 28 2020 | 11:04 午後

Thanks for your answer Jean-Francois. A big inconvenience for me but still a workaround!

It is still not clear as to how max handles distribution of computational load across the cores.
Are you saying that I need to start two different instances of Max in order to make use of multiple cores? So, even having two separate patchers is not enough? Because what Roman and Pablo suggested sounds like one can already utilize two cores by running two patchers within one instance of Max





Jean-Francois Charles's icon

Jean-Francois Charles

8月 29 2020 | 4:37 午前

"Are you saying that I need to start two different instances of Max in order to make use of multiple cores?"
You don't "need" to, but it's a reliable solution.

"having two separate patchers is not enough?": Pedro mentioned that the Audio part of separate top-level patchers are processed on separate threads, not the scheduler nor the low-priority data.
You can try to use the multi-core capabilities of poly~, but:
- that might be quite some work to convert / adapt your patches.
- you might gain some power by splitting some work across cores, but you might loose some because that splitting has to be managed, with some communication between the threads to take care of. That cost might or not be negligible compared to the processing cost of the poly~ voice itself.
- poly~ will split the work in separate threads, it's not guaranteed that it's processed on different cores. The OS will choose on which core to process the thread.
- that, I'm not sure, but I suspect that parallel in poly~ will only split the DSP into separate threads. The data processing (and CPU Jitter) will be stuck on one core anyway. Don't take my word for that: I hope someone here with more experience can con/in-firm.

When you open Max several times (same as "making several standalones", but more direct), you just need to remember that you can't communicate from one instance to the other with patch cables nor send/receive pairs: you have to use something like OSC, MIDI, audio signals, etc.

Note that even when you open Max several times (or use separate standalones), the OS will choose where to run them depending on what's best at the given time (often, it will be on different cores).

I mentioned this solution because I've met a number of seasoned users over the years, who have used it successfully.

Roman Thilenius's icon

Roman Thilenius

8月 29 2020 | 6:01 午前


in 99% of the cases distributing DSP to other cores is all you need.

adobe photoshop also only uses all cores for plug-ins, built-in image filters and mpeg/jpeg export, but not for dropdownmenus, file dialogs or for receiving a mouseclick.

and the more DSP is moved to extra cores, the more CPU is present for scheduler, runtime and OS tasks on the first core.

if i havent missed something, this will already work:

the core of cores (not related to corinna)


Wil's icon

Wil

5月 19 2021 | 5:02 午後

So I recently did this experiment.
I tried Roman‘s solution with pcontrol. Processor running at around 30% or higher cpu.
i tried Jean-Francois solutio with multiple standalones. same result.
then I tried opening half of the patch in one instance of Max, and using “open -n -a Max 8111” I opened the other half of the patch- each instance is running at about 13-15% cpu.

however. I cannot find a single object that will pass audio between instances. I can get udpsend/ revieve to work for sending messages, or even better spat5udspend,—- jit.net will not send audio. send~ receive~ does not seem to work between instances.

I really need to split up the audio processing.
delay time for sending doesn’t really matter.

there is no wired overlap in what I have built. I have 4 separate patches each doing something unique and different.
Input is patch 1. I can play through that and unprocessed sound is out put to my system.
Record/play is a patch 2 and receives audio from Input. These should both run in the first instance.
Surround is patch 3 and receives audio from the record/play patch. This is where I want to start the second instance of max.
Then a small output/record in a final patch.

so long story shortened- how do I send audio between separate instances of Max (after reading the past 15 years of threads nothing seems to work)?

Brian Kirkbride's icon

Brian Kirkbride

6月 04 2021 | 3:47 午後

You can use Rogue Amoeba’s Loopback or Soundflower to send audio from one instance of Max to another. Also, the thread below might apply just as well to inter-application audio communication...

Brian Kirkbride's icon

Brian Kirkbride

6月 04 2021 | 3:48 午後

Hmmm, forum prevented my link. Search for ”piping audio between macs” or see my posts.

Noise Wrangler's icon

Noise Wrangler

5月 02 2023 | 2:36 午後

Adding to the thread, because there's still not much about multithreading out there.

Using Max 8.5.4, the only reliable way of using all the cores I found is to use Roman's method of starting independent patchers and using send/receive between them.

The poly~ approach didn't work for me (but I haven't explored it much)

Damien Jacquet's icon

Damien Jacquet

7月 23 2024 | 4:01 午後

After some research, I found a trick to force max to use a given number of cores in apps or patcher with poly~ using the processor affinity on windows

you can try openning your standalone or max from the terminal with this command :

start "" /affinity 000FFF /realtime "C:\Program Files\Cycling '74\Max 8\Max.exe" "C:\Users\Bob\Documents\Max\Projects\MyProject.maxproj" 

Some explanations:

  • /affinity will force the threads of Max to be executed on some cores of CPU.

  • 000FFF is a hex binary mask that identify the cores on which you want the thread to be executed. convert it to binary, it gives you 000000000000111111111111. on my computer that has 24 logical processors (but 12 real cores), it means that only the 12 first are used.

  • /realtime elevates the priority of the app too run in realtime. Background apps will not be priorized over Max. use it carefully as it could easily block your computer : https://devblogs.microsoft.com/oldnewthing/20100610-00/?p=13753

You can also modify this by openning the task manager, then in the details tab, find your app and right cilck on it. the menu shows "set affinity" and you can check manually the UC on which you want Max to distribute the threads. Observe the effect on the CPU monitor in the audio settings.

Combined with the good parameters in poly~ (threadcount...) it should give you some extra CPU bandwidth

What is strange is that the best value I found on my Ryzen 7900 for my sound spatialization app is to check only 12 cores (which correspond to the true number of cores) and not all UC(Cores ? real Cores ? threads ? Logical Processors ? not really clear to me). If I check all processors in the affinity menu of the task manager, the processing is only shared by 4 Cores, leading to my CPU burning.

Hope this helps, and if some of you can explore also the same methods, I would be happy to understand more of that.

midinerd's icon

midinerd

7月 24 2024 | 1:02 午後

Fascinating, thanks so much for this - I will check into saturating the many cores I have with this suggestion.


I haven't tried using poly~ yet, looking forward to that.


The top-level patcher thing.. I tried that and wasn't having identifiable success with new top-level patchers going to separate cores :| though so many people (probably osx users?) are saying it's the way to go.


Hacky notes:
I also tested out launching separate instances of max on windows - by renaming max.exe to max-2.exe

It does work and follows the unshared memory space pattern of not being able to send/receive between instances. Though I want to say that I got the non max.exe (clones) to all crash at the same time unexpectedly, probably because it's a super hacky idea.

The same thing worked for the Nord G2 demo .exe, you can rename it and run multiple instances of that.

Roman Thilenius's icon

Roman Thilenius

7月 24 2024 | 3:29 午後

the main issue with running two instances of the same audio app is that they often partially share their prefs so that you might have set them to use the same IO drivers. for custom built max standalones you could avoid that constellation.