Skip to content

Add option to set idle priority#2708

Open
giraldeau wants to merge 2 commits intoninja-build:masterfrom
giraldeau:idle-priority
Open

Add option to set idle priority#2708
giraldeau wants to merge 2 commits intoninja-build:masterfrom
giraldeau:idle-priority

Conversation

@giraldeau
Copy link
Copy Markdown

Compiling on a desktop interfere with the interactive usage. For convenience, we add the option to lower the priority of the jobs.

On Windows, the priority is set to IDLE_PRIORITY_CLASS. On Unix, we lower the process priority with setpriority(). In both cases, the low priority is inherited by subprocess, such that setting the priority only once when ninja starts is sufficient.

Close #2176

Copy link
Copy Markdown
Contributor

@digit-google digit-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, a longer flag would be a good thing, imho. @jhasse please take a look.

@giraldeau
Copy link
Copy Markdown
Author

giraldeau commented Jan 29, 2026

Good point, I updated the patch to implement the long option. Thanks!

@digit-google
Copy link
Copy Markdown
Contributor

Thank you, please squash your commits into one, this will make the final git tree easier to understand.

Compiling on a desktop interfere with the interactive usage. For convenience, we add the option to lower the priority of the jobs.

On Windows, the priority is set to IDLE_PRIORITY_CLASS. On Unix, we lower the process priority with setpriority(). In both cases, the low priority is inherited by subprocess, such that setting the priority only once when ninja starts is sufficient.

Use long option --idle-priority for clarity.

Close ninja-build#2176
@giraldeau
Copy link
Copy Markdown
Author

Thank you, please squash your commits into one, this will make the final git tree easier to understand.

Done, and also rebased on the latest master. Cheers!

@elliotgoodrich
Copy link
Copy Markdown
Contributor

The linked article mentions specifically using low priority. Is there a reason idle has been chosen over low priority? From experience, I have found that idle worker threads can struggle to progress in a reasonable time.

@giraldeau
Copy link
Copy Markdown
Author

The linked article mentions specifically using low priority. Is there a reason idle has been chosen over low priority? From experience, I have found that idle worker threads can struggle to progress in a reasonable time.

The build will use all the CPU time that is isn't used by other process. Of course, if you have let say 2 builds at the same time, one with idle priority and the other with normal priority, then the idle priority will starve until the normal priority is finished.

But the main point of the feature is building in the background, and then doing something else during that time. I'm using it on a daily basis on Windows since a couple of months now, and it really helps to keep let other apps responsibe during a long build. I never had issue with a build that never finished.

On Linux, even with low priority, the scheduler will give some CPU slice once in a while, such that it still progress on a busy computer.

But look, let me do some experiments and I will get back with a clear picture with actual numbers on recent hardware and OS.

@elliotgoodrich
Copy link
Copy Markdown
Contributor

@giraldeau I checked up again on the previous experience with issues with idle priority and it was on a CPU with both E and P cores + running a high priority application so it may be quite a niche problem after all!

I suppose if you used idle-priority ninja with a high-CPU low priority application (e.g. MSBuild now) ninja may end up not getting any time until the other application finishes?

I can't find any good documentation on examples of when to use low priority, like there is documentation on idle priority.

Processes that monitor the system, such as screen savers or applications that periodically update a display, should use IDLE_PRIORITY_CLASS. This prevents the threads of this process, which do not have high priority, from interfering with higher priority threads.

Experiments using Windows and Linux shows that lowest priority level causes a typical build to almost stall when there exists a normal priority process running.

On Linux, priority level 10 will dedicate roughly 20% of the CPU time to the ninja process when there are a competing job.

On Windows, about the same result is obtained with the level BELOW_NORMAL_PRIORITY_CLASS, which is the priority level that is being used for a similar feature in MS Visual Studio.
@giraldeau
Copy link
Copy Markdown
Author

giraldeau commented Feb 13, 2026

I created two small utilities to measure the effect of the priority on runtime (when all CPUs are already busy) and latency that would have the build on other programs on the system [1]. Here are the results compiling ninja itself.

Windows 11, Intel Core i7-10850H

  • Latency baseline (sleep 10): 25ms
  • Latency with normal priority: 40ms
  • Latency with below normal priority: 25ms
  • Latency with idle priority: 25ms
  • Runtime baseline (no background load): 34s
  • Runtime baseline (with background load): 97s (~3x slowdown)
  • Runtime with below normal priority: starvation (still not finished at the time of writing)
  • Runtime with idle priority: 2022s (~60x slowdown, we can say its also starvation)

Ubuntu Linux 24.04, Intel Xeon Gold 6132

  • Latency baseline (sleep 10): 16ms
  • Latency with normal priority: 16ms
  • Latency with below normal priority: 16ms
  • Latency with idle priority: 16ms
  • Runtime baseline (no background load): 7.1s
  • Runtime baseline (with background load): 13s (~2x slowdown, as expected)
  • Runtime with below normal priority (nice 10): 60s (~5x slowdown)
  • Runtime with idle priority: 248s (~20x slowdown)

Therefore, the concerns of @elliotgoodrich are valid, and idle priority is too low. Using the below normal class helps to lower the latency on Windows, but you should use it only when there is actually unused CPU time on the system, otherwise the build is starving even with the below normal class. Windows schedule process in the below normal class only when no process in the higher priority classes are ready. Instead, we should change the priority level within the normal priority class, but that is not inherited on a process level.

On Linux, the niceness of 19 was also too low, and I changed it to 10, which is a more reasonable default. We notice there are no effect on latency, presumably because the latency monitor uses itself very little CPU time, and therefore gets selected to run as soon as it gets ready.

After these findings, let me check if we can adjust the priority level (and keep the priority class to normal) and solve the starvation on Windows.

Thanks again for your comments!

[1] (https://github.com/giraldeau/chooseprio/tree/master)[https://github.com/giraldeau/chooseprio/tree/master]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow setting the priority of spawned processes

3 participants