Ninja has been around for a while, since 2012 or so.
Ninja is a small build system with a focus on speed. https://ninja-build.org/
I had heard of it and an engineer I worked with at Cybex I think was using it as his build system. Ninja's goal is to be faster than GNUmake, the de-facto make utility.
David Rothlis did some benchmarks on ninja and the no-op build (a build with no or few changes vs. a clean build) is significantly faster with ninja.
I just started hacking on Kicad for fun. Kicad is an excellent open source electronics design tool that I've used to design and build several PCBs.
Kicad devs recommended using ninja for builds as its faster. Why not? Ninja has been around for a long time, so it should be pretty well developed, and it's a good opportunity to see how it works. If it works well it could be a good thing to adopt across a number of other projects that are presently using GNUmake.
So I'm off building Kicad, MacBook fans are cranking, cpu load is 1000% (which means several processors are working in parallel) and the code is building along rapidly. This is a good sign! GNUmake defaults to a single job (you can say make -jX to use X jobs instead, but you have to remember to do this). With a single job you end up with a single instance of the compiler building a single file.
Modern computers have several processor cores. Unlike GNUmake, ninja makes use of those processor cores by default, no command line arguments are necessary to get this parallel build behavior.
A few minutes later I noticed the terminal where I initiated the 'ninja' build had disappeared. That's odd... I immediately suspected the OOM killer (out-of-memory killer) but who knows...
Created a new terminal and kicked another ninja build off and it completed.
When I went to rebuild I was watching more carefully. Sure enough the same thing occurred. Now I really suspected the OOM killer. The OOM killer looks for processes that are using too much memory and if the system is at risk of slowing to the point of being unusable, it will kill the offending processes.
Sure enough looking at the logs via 'journalctl -r' it was an OOM situation:
Why is ninja causing an OOM condition? Is it something configured or used incorrectly?
In my case I'm using qemu to run Ubuntu 22.10. I've got an 8-core i9 2019 MacBook Pro with 32GB of ram. The vm is being given access to all processors (16), and half of the ram, 16GB.
Ninja is spawning jobs based on the 16 processors it sees being available. Ninja doesn't presently check how much memory is available on the system, and Kicad is complex enough that each instance of gcc is likely taking a few hundred megabytes to compile each file. At some point you end up with a handful gcc instances that are compiling particularly large files and the OOM sees that the gnome terminal, of which the ninja instance is a child, is taking up almost all of the system memory.
Others have reported hitting the same issue in GitHub issues, and there is this open issue, Ninja and RAM/Memory usage #2187.
Ninja is SO good at using all available compute resources that it ends up pushing ram usage far more than GNU make does. As I mentioned in my comment on issue #2187, I worry that far more people could be hitting this issue and switching away from ninja without reporting or debugging it.
So I can kick off a build and come back to it being complete rather than cancelled I'll have to figure out how to get ninja to not trigger the OOM condition. I think 'ninja -j10' or something could do it, we'll see!
Comments
Post a Comment