git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: Jeff King <peff@peff.net>
Cc: "SZEDER Gábor" <szeder.dev@gmail.com>,
	git@vger.kernel.org, "René Scharfe" <l.s.r@web.de>,
	"Derrick Stolee" <stolee@gmail.com>,
	"Julia Lawall" <Julia.Lawall@lip6.fr>,
	"Nicolas Palix" <npalix@diku.dk>,
	"Himanshu Jha" <himanshujha199640@gmail.com>
Subject: Re: [PoC] coccinelle: make Coccinelle-related make targets more fine-grained
Date: Thu, 02 Aug 2018 23:45:42 +0200	[thread overview]
Message-ID: <87bmaktpbt.fsf@evledraar.gmail.com> (raw)
In-Reply-To: <20180802180155.GD15984@sigill.intra.peff.net>


On Thu, Aug 02 2018, Jeff King wrote:

> On Thu, Aug 02, 2018 at 01:55:22PM +0200, SZEDER Gábor wrote:
>
>> Let's add a bit of Makefile metaprogramming to generate finer-grained
>> make targets applying one semantic patch to only a single source file,
>> and specify these as dependencies of the targets applying one semantic
>> patch to all source files.  This way that shell loop can be avoided,
>> semantic patches will only be applied to changed source files, and the
>> same semantic patch can be applied in parallel to multiple source
>> files.  The only remaining sequential part is aggregating the
>> suggested transformations from the individual targets into a single
>> patch file, which is comparatively cheap (especially since ideally
>> there aren't any suggestions).
>>
>> This change brings spectacular speedup in the scenario described in
>> point (1) above.  When the results of a previous 'make coccicheck' are
>> there, the time needed to run
>>
>>   touch apply.c ; time make -j4 coccicheck
>>
>> went from 3m42s to 1.848s, which is just over 99% speedup, yay!, and
>> 'apply.c' is the second longest source file in our codebase.  In the
>> scenario in point (2), running
>>
>>   touch contrib/coccinelle/array.cocci ; time make -j4 coccicheck
>>
>> went from 56.364s to 35.883s, which is ~36% speedup.
>
> I really like this direction. The slowness of coccicheck is one of the
> things that has prevented me from running it more frequently. And I'm a
> big fan of breaking steps down as much as possible into make targets. It
> lets make do its job (avoiding repeated work and parallelizing).

Yeah, this is great. Also, CC-ing some of the recent contributors to
linux.git's coccinelle, perhaps they're interested / have comments.

>> All the above timings are best-of-five on a machine with 2 physical
>> and 2 logical cores.  I don't have the hardware to bring any numbers
>> for point (3).  The time needed to run 'make -j4 coccicheck' in a
>> clean state didn't change, it's ~3m42s both with and without this
>> patch.
>
> On a 40-core (20+20) machine, doing "make -j40 coccicheck" from scratch
> went from:
>
>   real	1m25.520s
>   user	5m41.492s
>   sys	0m26.776s
>
> to:
>
>   real	0m24.300s
>   user	14m35.084s
>   sys	0m50.108s
>
> I was surprised by the jump in CPU times. Doing "make -j1 coccicheck"
> with your patch results in:
>
>   real	5m34.887s
>   user	5m5.620s
>   sys	0m19.908s
>
> so it's really the parallelizing that seems to be to blame (possibly
> because this CPU boosts from 2.3Ghz to 3.0Ghz, and we're only using 8
> threads in the first example).
>
>>   - [RFC]
>>     With this patch 'make coccicheck's output will look like this
>>     ('make' apparently doesn't iterate over semantic patches in
>>     lexicographical order):
>>
>>       SPATCH commit.cocci              abspath.c
>>       SPATCH commit.cocci              advice.c
>>       <... lots of lines ...>
>>       SPATCH array.cocci               http-walker.c
>>       SPATCH array.cocci               remote-curl.c
>>
>>     which means that the number of lines in the output grows from
>>     "Nr-of-semantic-patches" to "Nr-of-semantic-patches *
>>     Nr-of-source-files".
>
> IMHO this is not really that big a deal. We are doing useful work for
> each line, so to me it's just more eye candy (and it's really satisfying
> to watch it zip by on the 40-core machine ;) ).

FWIW on the 8-cpu box I usually test on this went from 2m30s to 1m50s,
so not a huge improvement in time, but nice to have the per-file
progress.

> What if we inverted the current loop? That is, right now we iterate over
> the cocci patches at the Makefile level, and then for each target we
> iterate over the giant list of source files. Instead, we could teach the
> Makefile to iterate over the source files, with a target for each, and
> then hit each cocci patch inside there.
>
> That would give roughly the same output as a normal build. But moreover,
> I wonder if we could make things faster by actually combining the cocci
> files into a single set of rules to be applied to each source file. That
> would mean invoking spatch 1/8 as much. It does give fewer opportunities
> for "make" to reuse work, but that only matters when the cocci files
> change (which is much less frequent than source files changing).
>
> Doing:
>
>   cat contrib/coccinelle/*.cocci >mega.cocci
>   make -j40 coccicheck COCCI_SEM_PATCHES=mega.cocci
>
> gives me:
>
>   real	0m17.573s
>   user	10m56.724s
>   sys	0m11.548s
>
> And that should show an improvement on more normal-sized systems, too,
> because we really are eliminating some of the startup overhead.
>
> The other obvious downside is that you don't get individual patches for
> each class of transformation. Do we care? Certainly for a routine "make
> coccicheck" I primarily want to know:
>
>   - is there something that needs fixing?
>
>   - give me the patch for all fixes
>
> So I wonder if we'd want to have that be the default, and then perhaps
> optionally give some targets to let people run single scripts (or not;
> they could probably just run spatch themselves).
>
>>   - [RFC]
>>     The overhead of applying a semantic patch to all source files
>>     became larger.  'make coccicheck' currently runs only one shell
>>     process and creates two output files for each semantic patch.
>>     With this patch it will run approx.  "Nr-of-semantic-patches *
>>     Nr-of-source-files" shell processes and create twice as many
>>     output files.
>
> Doing the "one big .cocci" would help with this, too (and again puts us
> in the same ballpark as a compile).
>
>>   - [RFC]
>>     This approach uses $(eval), which we haven't used in any of our
>>     Makefiles yet.  I wonder whether it's portable enough.  And it's
>>     ugly and complicated.
>
> I looked into this a long time ago for another set of Makefile patches I
> was considering. $(eval) was added to GNU make in 3.80, released in
> 2002. Which is probably fine by now.
>
> If it isn't, one more exotic option would be to push the coccicheck
> stuff into its own Makefile, and just run it via recursive make. Then
> anybody doing a vanilla build can do so even with an antique make, but
> you could only "make coccicheck" with something from the last 16 years
> (but good luck getting ocaml running there).
>
> I suspect if we go with the one-spatch-per-source route, though, that we
> could do this just with regular make rules.
>
> -Peff

  parent reply	other threads:[~2018-08-02 21:45 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-23 13:50 [PATCH 0/5] Misc Coccinelle-related improvements SZEDER Gábor
2018-07-23 13:50 ` [PATCH 1/5] coccinelle: mark the 'coccicheck' make target as .PHONY SZEDER Gábor
2018-07-23 14:36   ` Derrick Stolee
2018-07-23 19:37   ` Junio C Hamano
2018-07-23 13:50 ` [PATCH 2/5] coccinelle: use $(addsuffix) in 'coccicheck' make target SZEDER Gábor
2018-07-23 19:37   ` Junio C Hamano
2018-07-23 13:50 ` [PATCH 3/5] coccinelle: exclude sha1dc source files from static analysis SZEDER Gábor
2018-07-23 18:27   ` Eric Sunshine
2018-07-23 18:43     ` SZEDER Gábor
2018-07-23 18:57       ` Eric Sunshine
2018-07-23 13:50 ` [PATCH 4/5] coccinelle: put sane filenames into output patches SZEDER Gábor
2018-07-23 14:34   ` Derrick Stolee
2018-07-23 13:51 ` [PATCH 5/5] coccinelle: extract dedicated make target to clean Coccinelle's results SZEDER Gábor
2018-07-23 14:38 ` [PATCH 0/5] Misc Coccinelle-related improvements Derrick Stolee
2018-07-23 15:29 ` Duy Nguyen
2018-07-23 16:30 ` René Scharfe
2018-07-23 19:40 ` Junio C Hamano
2018-08-02 11:55 ` [PoC] coccinelle: make Coccinelle-related make targets more fine-grained SZEDER Gábor
2018-08-02 13:24   ` René Scharfe
2018-08-02 18:01   ` Jeff King
2018-08-02 18:31     ` Jeff King
2018-08-03  6:21       ` Jonathan Nieder
2018-08-03 13:08         ` Jeff King
2018-08-05 23:02           ` Jonathan Nieder
2018-08-02 19:46     ` Eric Sunshine
2018-08-02 21:29       ` Jeff King
2018-08-02 21:45     ` Ævar Arnfjörð Bjarmason [this message]
2018-08-03  6:22       ` Julia Lawall
2018-08-03  6:44         ` Jonathan Nieder
2018-08-03  6:52           ` Julia Lawall
2018-08-03  6:25       ` Julia Lawall

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-all 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=87bmaktpbt.fsf@evledraar.gmail.com \
    --to=avarab@gmail.com \
    --cc=Julia.Lawall@lip6.fr \
    --cc=git@vger.kernel.org \
    --cc=himanshujha199640@gmail.com \
    --cc=l.s.r@web.de \
    --cc=npalix@diku.dk \
    --cc=peff@peff.net \
    --cc=stolee@gmail.com \
    --cc=szeder.dev@gmail.com \
    /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;
as well as URLs for NNTP newsgroup(s).