Re: Add support for limiting CPU pressure

2022-12-21 Thread Paul Smith
On Wed, 2022-12-21 at 15:00 -0500, Randy MacLeod wrote:
> What tests were you running to check these improvements?

The GNU project doesn't have the resources to perform large-scale
testing.  We run our regression tests before pushing any code, but
that's about all we can manage.  The only regular testing we do of -l
is to ensure it works (we set the load so low that we're guaranteed to
get serialized builds regardless of -j, and make sure that's so).

Before pulling these changes in I did some straightforward testing
myself, by simply running a large build (GCC IIRC) and verifying, by
spot-checking, that we never had too many jobs running.

I'm confident I didn't try running multiple disjoint invocations of
make in parallel to see what the load was like.

I'm always excited to get more testing!  Either from the Git
repository, or especially during the release candidate cycle: all RC
builds are announced on this list and anyone who has the facilities to
stress-test the RC builds would be most appreciated!



Re: Add support for limiting CPU pressure

2022-12-21 Thread Randy MacLeod

On 2022-12-21 11:24, Paul Smith wrote:

On Tue, 2022-12-20 at 16:59 -0500, Randy MacLeod wrote:

While we are doing development with Yocto Project (1), a source-
based Linux distro builder, we found that many instances of making
running in parallel with other work can overload even a large
many-core build machine. Existing mechanisms that are either not
system-wide (-j) or are too slow(-l has 1 minute averaging), so in
order to make optimal use of a multi-core system for some larger
tasks we need a new mechanism.

Can you clarify what version of GNU make you're using?

4.3 from ubuntu-22.04 but the build pool for Yocto
has ~15 distros of various vintages as well as being
able to use the version of make (4.4) that we carry on

the oe-core master branch:

  https://layers.openembedded.org/layerindex/recipe/245/
http://cgit.openembedded.org/openembedded-core/tree/meta/recipes-devtools/make/make_4.4.bb

For any work we do here, we'd use that master branch version rather than
the older host version.



There have been a number of efforts to improve the accuracy of -l and
it does not (any longer) use a simple load detection, for EXACTLY this
reason (the value is too coarse, particularly at startup).

Okay. I'll try to allocate time to see what happens with 4.4.


In the latest version GNU make 4.4, it will use the content of
/proc/loadavg (if it exists) to figure out how many jobs are currently
executing on the system and use that as a measurement of load.

If that's not available, we use getloadavg() but we do some math on it
to modify the load average based on the number of jobs we've started in
the last second.  Of course, this also suffers from the problem that it
only knows about jobs that THIS INSTANCE of make has started in the
last second.

Anyway you can read more about this in the comments in the source code:

https://git.savannah.gnu.org/cgit/make.git/tree/src/job.c?h=4.4#n1953


Thanks, I missed the recent changes amongst the decades old code! ;-)

What tests were you running to check these improvements?

--
# Randy MacLeod
# Wind River Linux




Re: Add support for limiting CPU pressure

2022-12-21 Thread Paul Smith
On Tue, 2022-12-20 at 16:59 -0500, Randy MacLeod wrote:
> > While we are doing development with Yocto Project (1), a source-
> > based Linux distro builder, we found that many instances of making
> > running in parallel with other work can overload even a large 
> > many-core build machine. Existing mechanisms that are either not
> > system-wide (-j) or are too slow(-l has 1 minute averaging), so in 
> > order to make optimal use of a multi-core system for some larger
> > tasks we need a new mechanism.

Can you clarify what version of GNU make you're using?

There have been a number of efforts to improve the accuracy of -l and
it does not (any longer) use a simple load detection, for EXACTLY this
reason (the value is too coarse, particularly at startup).

In the latest version GNU make 4.4, it will use the content of
/proc/loadavg (if it exists) to figure out how many jobs are currently
executing on the system and use that as a measurement of load.

If that's not available, we use getloadavg() but we do some math on it
to modify the load average based on the number of jobs we've started in
the last second.  Of course, this also suffers from the problem that it
only knows about jobs that THIS INSTANCE of make has started in the
last second.

Anyway you can read more about this in the comments in the source code:

https://git.savannah.gnu.org/cgit/make.git/tree/src/job.c?h=4.4#n1953



Re: Add support for limiting CPU pressure

2022-12-20 Thread Randy MacLeod

Re-send now that I've subscribed from my work email as well as my
gmail account.



Thanks for the comment Howard.

On 2022-12-20 16:02, Howard Chu wrote:

cont...@zhengqiu.net wrote:

Hello,

While we are doing development with Yocto Project (1), a source-
based Linux distro builder, we found that many instances of making
running in parallel with other work can overload even a large
many-core build machine. Existing mechanisms that are either not
system-wide (-j) or are too slow(-l has 1 minute averaging), so in
order to make optimal use of a multi-core system for some larger
tasks we need a new mechanism.



All the tests are done using an Ubuntu System, as we are not very lucky to
find similar features on macOS/Windows, so if you know anything, please
help us out! Additionally, we also want to gather more data, so if you know
any other large packages that make is often tested with, please let us know
as well!


Relying on a new non-portable kernel feature sounds like a pretty bad idea.
Especially when you can easily solve the "not system-wide" aspect of "make -j"
portably: by using a named pipe. It should be a simple job to patch make to
create or reference a named pipe in an initial invocation, and the rest of
the existing jobserver machinery will Just Work after that, and all of
the relevant OSs have support for named pipes.




We did consider this approach and it can work in some but certainly
not all use cases and not the ones where this approach has the
most impact.

It could work where we "only" have one bitbake build
  (bitbake is the build tool used in the yocto world)
running and we want to share jobs across this single bitbake build.
We'd still have a problem with recipes (packages) that do not use make
to build and that don't have a job server design. While we could add
that feature to the other build tools such as ninja, it seems that PSI
is a more generic solution.

What this approach doesn't deal with occurs when there are several
bitbake builds that are all independently running or a situation where
there are say a couple of bitbake builds, a CPU intensive runtime
test using qemu and a clean-up job all running at the same time.
That may seem like an unusual use-case but the generic version is
that you want to do a build but you want to back-off if other processes
in any account, are also loading the machine that you are using. If
several users or builds are all using the same PSI back-off mechanism
then the system will be less likely to get into an overload or even a
process thrashing situation.

The shared job server approach is a good idea but has more limited
applicability, right?


Also, I'm re-posting the original thread below for the archives since
Zheng's email wasn't plain text and didn't get archived properly.
Oh and I have one comment below for Zheng.

I'll trim  the thread on any follow-up.

Thanks,

../Randy




Hello,

While we are doing development with Yocto Project (1), a source-
based Linux distro builder, we found that many instances of making
running in parallel with other work can overload even a large 
many-core build machine. Existing mechanisms that are either not
system-wide (-j) or are too slow(-l has 1 minute averaging), so in 
order to make optimal use of a multi-core system for some larger

tasks we need a new mechanism. We found that on Linux, for the
4.20 kernel and later, a feature called Pressure Stall Information (PSI(2)) 
can provide system-wide metrics indicating when and by how much a system

is experiencing cpu, memory or io pressure.

So we implemented a new feature that uses /proc/pressure/cpu info to
limit new task creation. We previously implemented it for bitbake: 
, 
and find limiting tasks by using proc/pressure/cpu can significantly reduce 
system latency and CPU contention after Yocto uses this feature from
bitbake, their CPU contention-related errors have been reduced to about 
once every two months compared to several times every week.


Here is the commit we have, although it needs to be cleaned up before commit,
it works fine when we tested it with OpenSSL on a 4-core system and found the
CPU pressure can be reduced by 20% while keeping the run time about the same.
This is not ideal though, so we also want to see if you have any suggested 
improvements
to this algorithm.

$ hyperfine --runs 5 'make clean && /usr/bin/time -o build-time-0.log 
./../mymake -j'
Benchmark 1: make clean && /usr/bin/time -o build-time-0.log ./../mymake -j
  Time (mean ± σ): 179.994 s ±  0.418 s[User: 576.071 s, System: 56.747 
s]
  Range (min … max):   179.383 s … 180.441 s5 runs
 
$ hyperfine --runs 5 'make clean && /usr/bin/time -o build-time-0.log ./../mymake -j -z 10'

Benchmark 1: make clean && /usr/bin/time -o build-time-0.log ./../mymake -j -z 
10
  Time (mean ± σ): 166.372 s ±  4.976 s[User: 538.634 s, System: 59.617 
s]
  Range (min … max):   159.443 s … 171.906 s5 runs
 
$ hyperfine --runs 5 'make clean && /usr/bin/time -o 

Re: Add support for limiting CPU pressure

2022-12-20 Thread Randy MacLeod

Thanks for the comment Howard.

On 2022-12-20 16:02, Howard Chu wrote:

cont...@zhengqiu.net wrote:

Hello,

While we are doing development with Yocto Project (1), a source-
based Linux distro builder, we found that many instances of making
running in parallel with other work can overload even a large
many-core build machine. Existing mechanisms that are either not
system-wide (-j) or are too slow(-l has 1 minute averaging), so in
order to make optimal use of a multi-core system for some larger
tasks we need a new mechanism.



All the tests are done using an Ubuntu System, as we are not very lucky to
find similar features on macOS/Windows, so if you know anything, please
help us out! Additionally, we also want to gather more data, so if you know
any other large packages that make is often tested with, please let us know
as well!


Relying on a new non-portable kernel feature sounds like a pretty bad idea.
Especially when you can easily solve the "not system-wide" aspect of "make -j"
portably: by using a named pipe. It should be a simple job to patch make to
create or reference a named pipe in an initial invocation, and the rest of
the existing jobserver machinery will Just Work after that, and all of
the relevant OSs have support for named pipes.




We did consider this approach and it can work in some but certainly
not all use cases and not the ones where this approach has the
most impact.

It could work where we "only" have one bitbake build
  (bitbake is the build tool used in the yocto world)
running and we want to share jobs across this single bitbake build.
We'd still have a problem with recipes (packages) that do not use make
to build and that don't have a job server design. While we could add
that feature to the other build tools such as ninja, it seems that PSI
is a more generic solution.

What this approach doesn't deal with occurs when there are several
bitbake builds that are all independently running or a situation where
there are say a couple of bitbake builds, a CPU intensive runtime
test using qemu and a clean-up job all running at the same time.
That may seem like an unusual use-case but the generic version is
that you want to do a build but you want to back-off if other processes
in any account, are also loading the machine that you are using. If
several users or builds are all using the same PSI back-off mechanism
then the system will be less likely to get into an overload or even a
process thrashing situation.

The shared job server approach is a good idea but has more limited
applicability, right?


Also, I'm re-posting the original thread below for the archives since
Zheng's email wasn't plain text and didn't get archived properly.
Oh and I have one comment below for Zheng.

I'll trim  the thread on any follow-up.

Thanks,

../Randy




Hello,

While we are doing development with Yocto Project (1), a source-
based Linux distro builder, we found that many instances of making
running in parallel with other work can overload even a large 
many-core build machine. Existing mechanisms that are either not
system-wide (-j) or are too slow(-l has 1 minute averaging), so in 
order to make optimal use of a multi-core system for some larger

tasks we need a new mechanism. We found that on Linux, for the
4.20 kernel and later, a feature called Pressure Stall Information (PSI(2)) 
can provide system-wide metrics indicating when and by how much a system

is experiencing cpu, memory or io pressure.

So we implemented a new feature that uses /proc/pressure/cpu info to
limit new task creation. We previously implemented it for bitbake: 
, 
and find limiting tasks by using proc/pressure/cpu can significantly reduce 
system latency and CPU contention after Yocto uses this feature from
bitbake, their CPU contention-related errors have been reduced to about 
once every two months compared to several times every week.


Here is the commit we have, although it needs to be cleaned up before commit,
it works fine when we tested it with OpenSSL on a 4-core system and found the
CPU pressure can be reduced by 20% while keeping the run time about the same.
This is not ideal though, so we also want to see if you have any suggested 
improvements
to this algorithm.

$ hyperfine --runs 5 'make clean && /usr/bin/time -o build-time-0.log 
./../mymake -j'
Benchmark 1: make clean && /usr/bin/time -o build-time-0.log ./../mymake -j
  Time (mean ± σ): 179.994 s ±  0.418 s[User: 576.071 s, System: 56.747 
s]
  Range (min … max):   179.383 s … 180.441 s5 runs
 
$ hyperfine --runs 5 'make clean && /usr/bin/time -o build-time-0.log ./../mymake -j -z 10'

Benchmark 1: make clean && /usr/bin/time -o build-time-0.log ./../mymake -j -z 
10
  Time (mean ± σ): 166.372 s ±  4.976 s[User: 538.634 s, System: 59.617 
s]
  Range (min … max):   159.443 s … 171.906 s5 runs
 
$ hyperfine --runs 5 'make clean && /usr/bin/time -o build-time-0.log ./../mymake -j -z 50'

Benchmark 1: make clean && /usr/bin/time -o 

Re: Add support for limiting CPU pressure

2022-12-20 Thread Howard Chu via Bug reports and discussion for GNU make
cont...@zhengqiu.net wrote:
> Hello,
> 
> While we are doing development with Yocto Project (1), a source-
> based Linux distro builder, we found that many instances of making
> running in parallel with other work can overload even a large 
> many-core build machine. Existing mechanisms that are either not
> system-wide (-j) or are too slow(-l has 1 minute averaging), so in 
> order to make optimal use of a multi-core system for some larger
> tasks we need a new mechanism.

> All the tests are done using an Ubuntu System, as we are not very lucky to 
> find similar features on macOS/Windows, so if you know anything, please 
> help us out! Additionally, we also want to gather more data, so if you know
> any other large packages that make is often tested with, please let us know
> as well!

Relying on a new non-portable kernel feature sounds like a pretty bad idea.
Especially when you can easily solve the "not system-wide" aspect of "make -j"
portably: by using a named pipe. It should be a simple job to patch make to
create or reference a named pipe in an initial invocation, and the rest of
the existing jobserver machinery will Just Work after that, and all of
the relevant OSs have support for named pipes.

-- 
  -- Howard Chu
  CTO, Symas Corp.   http://www.symas.com
  Director, Highland Sun http://highlandsun.com/hyc/
  Chief Architect, OpenLDAP  http://www.openldap.org/project/