-
-
Notifications
You must be signed in to change notification settings - Fork 15.5k
buildRustCrate: use $NIX_BUILD_CORES for each of the crates #57936
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@GrahamcOfBorg build cargo-vendor |
The reason is the grain of parallelism we want: rustc alone is not capable of predicting the number of available cores, I believe Cargo does something like that, where the last step is parallelized on all cores. Unfortunately, this would be hard to model in a purely functional way. If we don't restrict this, Nix runs on all available cores, and each rustc runs on all available cores, so we get n^2 threads, which is really bad for performance (and super heavy on memory). |
That is why I am using Having used that on a few projects now it seems to just do what is expected. Us up to My concerns (and thus asking you) were if there was some build breakage that you initially observed that would be a blocker for this. |
I have never seen any problem related to this, I think it's fine. So, let's say I have 5 cores, what setting should I choose if I want to keep my cores as busy as possible, but not oversubscribe? |
That is a tradeoff that you have to make yourself. One simple solution would be to always have Oversubscribing should not be that bad with decent scheduling. That is a completely different research topic.. |
Ok, maybe I wasn't clear in my first post, because I'm not sure I get it. Nix runs in parallel on $NIX_BUILD_CORES cores, by launching multiple processes. Rustc also tries to runs in parallel. Let's say we set NIX_BUILD_CORES to the number of cores on the machine. They don't know about each other, so they will both try to use all cores available on the machine, by launching a quadratic number of jobs. But if we let one of them deal with it completely, we could get a more optimal number of jobs:
However, allowing both Nix and Rustc to start N jobs does result in machine hanging, crazy memory usage filling all the swap+memory, etc. That has happened to me many times, and is the reason why I changed that setting from "all available cores on both" to "all available cores on Nix, 1 on Rustc". My builds now run in parallel, and much much faster than with the previous quadratic strategy, because they don't fill the memory, and don't spend their whole time in context switches. |
I hope I can help explain this a bit. Nix has two relevant settings with regards to how your CPU cores will be utilized:
The total number of consumed cores is a simple multiplication, The balance on how to set these two independent variables depends upon each builder's workload and hardware. Here are a few example scenarios on a machine with 24 cores:
Right now, it is up to the builders to respect host's requested cores-per-build by following I don't believe Nix currently reduces the actual, total number of available cores with something like Does this help? ps: |
Ok, this is more clever and subtle than how I usually use Nix. So, indeed setting the variable to |
The codegen-units setting affects the build output and must be set consistently.
Motivation for this change
I started to compile a project over and over and over and over again and was wondering why not all of my cores where being used like when compiling with
cargo
in development mode.@P-E-Meunier you restricted the core count to 1 back in #39003. Was there some specific reasoning?
Things done
sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)nix path-info -S
before and after)