public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Laszlo Ersek <lersek@redhat.com>
To: "Gao, Liming" <liming.gao@intel.com>
Cc: edk2-devel-01 <edk2-devel@lists.01.org>,
	"Philippe Mathieu-Daudé" <philmd@redhat.com>
Subject: parallelism in the module-level, generated GNUmakefile's
Date: Tue, 22 Jan 2019 13:54:31 +0100	[thread overview]
Message-ID: <d2a83e60-50f1-33d9-4c9d-34d3d947ff42@redhat.com> (raw)

Hi Liming,

I'd like to ask a question about parallel ("multi threaded") make.

The use case is the following:

(1) The edk2 "build" BaseTools utility itself is invoked from a
*higher-level* Makefile that is outside of the edk2 project.

(2) The outer make process is invoked with "make -jN".

(3) The "build" utility is invoked in isolation. That is, at most *one*
instance of the "build" utility runs at any given time, despite the
outer make receiving "-jN". This guarantees that there is no corruption
in $WORKSPACE/Conf and so on.

(4) The "build" utility is invoked with the "-m" option, to build a
single module INF.

(5) The "-n" parameter of the "build" utility is not used (and it would
be useless anyway, since "-n" only parallelizes the build *between* INF
files, and not *within* INF files, and here we run "build" on a single
INF file, with "-m").


As a result, when the "build" utility invokes the "make" program, on the
GNUmakefile that was generated by "GenMake.py", there is already a
higher-level make process that is the (indirect) ancestor of the new
make process. This is important because the higher level make process
sets some options in the MAKEFLAGS environment variable, and the inner
make process inherits those:

           outer make --> sets MAKEFLAGS in the environment
               |
               |
           build \
             -a ARCH \
             -p PLATFORM_DSC \
             -t TOOLCHAIN_TAG \
             -b TARGET \
             -m MODULE_INF
               |
               |
           inner make --> inheirts MAKEFLAGS in the environment

Due to (2), the *inner* make inherits the following MAKEFLAGS:

  --jobserver-fds=3,4 -j

The "-j" and "--jobserver-fds" options cause the inner make -- which is
started by "build" -- to communicate with the *outer* make process. The
goal of this communication is to ensure that no more than 4 jobs are
active at any given time.

The important part is that, if the "job server" (provided by the outer
make) *allows* the inner make to run two or more recipes in parallel,
from the generated GNUMakefile, then the inner make *will do that*. It
will launch multiple "nasm", "gcc", "iasl" etc commands in parallel.

In my testing, this happens to work fine -- the build completes okay. My
question is:

- Is this behavior *intentional*?

- In other words: does "GenMake.py" *intentionally* generate
"GNUmakefile" so that it is compatible with "make -j"? Or does it work
only by chance, on my end?


If the answer is "by chance only", then that is 100% fine with me; I am
not requesting that we add "make -j" compatibility to "GenMake.py".
Instead, I'd suggest that we expose this limitation *explicitly* in
"GenMake.py". For that, the ".NOTPARALLEL" target can be used, and it
really has to be placed into the generated GNUMakefile:

https://www.gnu.org/software/make/manual/make.html#index-_002eNOTPARALLEL

If we do that, then the inner make will safely ignore the inherited "-j"
option, for the targets that are listed as prerequisites of .NOTPARALLEL.

And then the problem becomes: how can we collect the full set of
GNUMakefile targest (so that we can list them all in .NOTPARALLEL)?
There are many types of build products, from iasl, nasm, VfrCompile,
etc, beyond the most common "object file from C source".

Thanks!
Laszlo


             reply	other threads:[~2019-01-22 12:54 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-22 12:54 Laszlo Ersek [this message]
2019-01-23 16:36 ` parallelism in the module-level, generated GNUmakefile's Gao, Liming
2019-01-23 22:07   ` Laszlo Ersek
2019-01-24  9:57     ` Gao, Liming
2019-01-24 11:40       ` Laszlo Ersek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d2a83e60-50f1-33d9-4c9d-34d3d947ff42@redhat.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox