guysoft / OctoPi

Scripts to build OctoPi, a Raspberry PI distro for controlling 3D printers over the web
GNU General Public License v3.0
2.45k stars 367 forks source link

[BRAINSTORMING] - Firstboot / CPU Pinning #732

Open kantlivelong opened 3 years ago

kantlivelong commented 3 years ago

Curious as to what you think of implementing these two before I put in the effort towards a PR.

Example config:

# /etc/systemd/system.conf
CPUAffinity=0-2
# /etc/systemd/system/octoprint.service.d/override.conf
[Service]
CPUAffinity=3

Thoughts?

guysoft commented 3 years ago

I am not sure if it will have any positive or negative impact. Have you tried manually setting it up and seeing how it behaves?

kantlivelong commented 3 years ago

So I've done this on my setup for a while now without any negative effects. You won't really see any benefits unless the system is under load. A simple way to test is to run an instance of dd(dd if=/dev/urandom of=/dev/null) per core then try printing an object with small rounded corners. You should see the machine stutter.

guysoft commented 3 years ago

@kantlivelong If you CPU pin and then run the dd command above, does it not stutter? If so, its really worth considering adding this. cc @foosel

foosel commented 3 years ago

Sounds reasonable.

kantlivelong commented 3 years ago

@kantlivelong If you CPU pin and then run the dd command above, does it not stutter?

It does not. 😄

cp2004 commented 3 years ago

Would this make any difference to a plugin that uses the Python multiprocessing module. Context would be WS281x LED Status, the LED strip & it's animations are controlled from a process using multiprocessing. Of course, I could try it but wondering if anyone knew the answer first 🙂

kantlivelong commented 3 years ago

With the given config any process spawned by octoprint will also be pinned to the same CPU. It might help but really the best way to go about it would be to offload that to a simple micro/arduino.

cp2004 commented 3 years ago

I am more worried about it breaking than helping, so as long as it won't explode then it should be fine. The effect runner code is not heavy (it sleeps most of the time), it is just in a separate process to simplify things and avoid the library segfaulting when used with threading... Maybe I'll give this a test at some point 👀

kantlivelong commented 3 years ago

I am more worried about it breaking than helping, so as long as it won't explode then it should be fine. The effect runner code is not heavy (it sleeps most of the time), it is just in a separate process to simplify things and avoid the library segfaulting when used with threading... Maybe I'll give this a test at some point eyes

Nah shouldn't cause an issue there. All the change does is instruct systemd to launch procs on CPUs 0-2 by default and then specifically use 3 for octoprint and it's child processes.

guysoft commented 3 years ago

Its worth adding this to the nightly build and see what people report. That way we could see if its breaking something. I think on the brainstorming level of an idea - it sounds like the effort of the PR is worth it. But it might need to be reverted later if we see its causing issues (a squish commit might be a good idea to track it down in case of a revert).

foosel commented 3 years ago

specifically use 3 for octoprint and it's child processes.

Hmmmmm... Ok, now THAT has me worried. I put the GCODE analysis on its own process precisely so that on a multi processor setup it could use a different CPU than the one that OctoPrint's main process is on. If there's no way to pin only the main OctoPrint process to one CPU I'll have to retract my vote, because that then kinda defeats a lot of conscious decisions put into the internal architecture the past years ever since we started to get multicore pis.

kantlivelong commented 3 years ago

Ah good call. The only way around that would be to reset affinity after forking processes which means core code changes. Not exactly a bad feature but it does add more complexity.

foosel commented 3 years ago

Doesn't sound like something I could easily add without having a ton of platform compatibility overhead?

kantlivelong commented 3 years ago

psutil provides a method to set affinity that works across all platforms. Poking at the OctoPrint source it looks like processes are executed using octoprint.util.commandline. So the processes could be executed, set affinity, then wait.

So it's technically doable without too much effort but that won't help plugins unless they make use of the same class (thinking of doing that myself now).

Agh!

I wonder if simply changing the priority would yield similar results without having to pin. Might test that later.

cryptoAlgorithm commented 2 years ago

About determining how many CPUs are available, why not just always pin OctoPrint to CPU 0? That would work in all scenarios and shouldn't have any negative impact (unless there are also a bunch of processes pinned to that CPU)