One idea we'd tossed around is that you could annotate a given build
rule with some "metric" attribute that Ninja would attempt to balance
without needing to know what the metric is. For example, if your
build is memory-constrained you could tag each build rule with an
estimation of how much memory that rule would take, and then you could
tell Ninja to run as many jobs as possible such that the sum of the
metric is below some specified limit.
In some sense that's just a generalization of the current -j behavior
where each job has an implied metric value of 1.
But maybe all of what I just described is too generic and not
pragmatic enough; maybe the only metrics real projects care about are
memory and CPU. I know in Chrome's case we couldn't run multiple
links at the same time due to memory constraints...
> Ninja has the -j setting to decide how parallel the build process is, but
> it's a static decision. My build spawns lots of lightweight builds
> initially, then very memory-hungry processes later. I'm running on a slice
> of a 6 CPU machine. The outcome is the fastest way to build is to set -j16
> to start, then Ctrl-C the build when it starts to run out of memory & page
> to disk, then switch to -j2. I also have to watch out that I don't hog the
> CPU resources for other users.
>
> Could there be a dynamic solution for this? Perhaps specify how much CPU &
> memory you want to use and Ninja allocates the appropriate number of threads
> dynamically? Also the previous timing information in the logs might provide
> a hint on how to long each build target will take to run. You could extend
> the log with peak memory requirements.
>
On Thu, Jul 19, 2012 at 11:42 AM, Evan Martin <mar...@danga.com> wrote:We this issue in chromium-land with compiler processes too: When ninja
> One idea we'd tossed around is that you could annotate a given build
> rule with some "metric" attribute that Ninja would attempt to balance
> without needing to know what the metric is. For example, if your
> build is memory-constrained you could tag each build rule with an
> estimation of how much memory that rule would take, and then you could
> tell Ninja to run as many jobs as possible such that the sum of the
> metric is below some specified limit.
>
> In some sense that's just a generalization of the current -j behavior
> where each job has an implied metric value of 1.
>
> But maybe all of what I just described is too generic and not
> pragmatic enough; maybe the only metrics real projects care about are
> memory and CPU. I know in Chrome's case we couldn't run multiple
> links at the same time due to memory constraints...
(or make) builds all the V8DerivedSourcesNN.cpp files, normal
computers get very slow.
I think it'd be useful if ninja wouldn't start new processes if it
notices the system is low on memory and at least 1 ninja child is
running. I don't know how feasible it is to detect "low on memory"
though.
Nico
>
> On Thu, Jul 19, 2012 at 10:54 AM, Richard Geary <richar...@gmail.com> wrote:
>> Ninja has the -j setting to decide how parallel the build process is, but
>> it's a static decision. My build spawns lots of lightweight builds
>> initially, then very memory-hungry processes later. I'm running on a slice
>> of a 6 CPU machine. The outcome is the fastest way to build is to set -j16
>> to start, then Ctrl-C the build when it starts to run out of memory & page
>> to disk, then switch to -j2. I also have to watch out that I don't hog the
>> CPU resources for other users.
>>
>> Could there be a dynamic solution for this? Perhaps specify how much CPU &
>> memory you want to use and Ninja allocates the appropriate number of threads
>> dynamically? Also the previous timing information in the logs might provide
>> a hint on how to long each build target will take to run. You could extend
>> the log with peak memory requirements.
>>
Perhaps a metrics approach with some solid default implementations (i.e. a memory metric which is proportional to the size of the inputs, a cpu metric which takes an estimated expected load, 'no more than X of this rule at a time', etc.) could work. Keeps the ninja-side implementation clean, but addresses the practical concerns.
I'd love to help implement this.
For what it's worth, I prototyped free-ram-guided thread counts in https://github.com/nico/ninja/compare/memlimit a while ago for OS X, but it didn't really go anywhere. (It works well, but it has 100 MB as free memory hardcoded and it's specific to ram. I guess cpu is already handled by the existing -l mode, but doing this for disk i/o is tricky. On the plus side, it doesn't need to store anything anywhere.)