rust-osdev / bootloader

An experimental pure-Rust x86 bootloader
Apache License 2.0
1.39k stars 212 forks source link

Memory use during build #404

Open m-mueller678 opened 12 months ago

m-mueller678 commented 12 months ago

I was trying to build bootloader on my notebook with 4GB ram. Unfortunately, it runs out of memory and becomes unbearably slow with swapping. I think this is due to the parallel build of boot stages. It would be neat to have an option to build them sequentially.

bjorn3 commented 12 months ago

You can pass -j1 to cargo to build only a single crate at a time.

m-mueller678 commented 12 months ago

I am talking about this part of the build script that launches multiple cargo instances in parallel

// Run the bios build commands concurrently.
// (Cargo already uses multiple threads for building dependencies, but these
// BIOS crates don't have enough dependencies to utilize all cores on modern
// CPUs. So by running the build commands in parallel, we increase the number
// of utilized cores.)
#[cfg(not(docsrs_dummy_build))]
let (bios_boot_sector_path, bios_stage_2_path, bios_stage_3_path, bios_stage_4_path) = (
    build_bios_boot_sector(&out_dir),
    build_bios_stage_2(&out_dir),
    build_bios_stage_3(&out_dir),
    build_bios_stage_4(&out_dir),
).join().await;

passing -j1 does not help with that.

bjorn3 commented 12 months ago

passing -j1 does not help with that.

As far as I understand the jobserver should be passed through to those cargo sub invocations using CARGO_MAKEFLAGS and thus -j1 should limit the amount of processes across all those cargo instances.

m-mueller678 commented 12 months ago

I am not familiar with cargo internals, but I have observed at least three concurrent rustc invocations in top.

bjorn3 commented 12 months ago

I think I get it. I think all four cargo invocations assumed they had an implicit token from getting spawned as they normally would and thus they all thought it would be fine to spawn one rustc instance. One fix for that would be to use the jobserver crate inside the build script to limit spawning new cargo invocations based on if a jobserver token is available.

phil-opp commented 12 months ago

Thanks for reporting this issue!

One fix for that would be to use the jobserver crate inside the build script to limit spawning new cargo invocations based on if a jobserver token is available.

I'm not familiar with the make jobserver, but this sounds like a good approach.

Alternatively, we could also read the NUM_JOBS env variable, which cargo sets for build scripts, and use that to limit the amount of concurrency for these subcommands.

As a side note, I plan to replace these nested cargo invocations with artifact dependencies eventually, but right now we're blocked because we need build-std (see https://github.com/rust-lang/cargo/issues/10444).