index-pack: make quantum of work smaller
authorJonathan Tan <jonathantanmy@google.com>
Tue, 8 Sep 2020 19:48:35 +0000 (12:48 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 8 Sep 2020 22:52:17 +0000 (15:52 -0700)
commitf08cbf60fe11507b5ff722ceae95dfb86ce654ee
treed3369b36ff8a18fdce0bcf17aa9b644f734d4e7a
parentee6f058384aa61ec175de9e45f413f209c6bf1dc
index-pack: make quantum of work smaller

Currently, when index-pack resolves deltas, it does not split up delta
trees into threads: each delta base root (an object that is not a
REF_DELTA or OFS_DELTA) can go into its own thread, but all deltas on
that root (direct or indirect) are processed in the same thread.

This is a problem when a repository contains a large text file (thus,
delta-able) that is modified many times - delta resolution time during
fetching is dominated by processing the deltas corresponding to that
text file.

This patch contains a solution to that. When cloning using

  git -c core.deltabasecachelimit=1g clone \
    https://fuchsia.googlesource.com/third_party/vulkan-cts

on my laptop, clone time improved from 3m2s to 2m5s (using 3 threads,
which is the default).

The solution is to have a global work stack. This stack contains delta
bases (objects, whether appearing directly in the packfile or generated
by delta resolution, that themselves have delta children) that need to
be processed; whenever a thread needs work, it peeks at the top of the
stack and processes its next unprocessed child. If a thread finds the
stack empty, it will look for more delta base roots to push on the stack
instead.

The main weakness of having a global work stack is that more time is
spent in the mutex, but profiling has shown that most time is spent in
the resolution of the deltas themselves, so this shouldn't be an issue
in practice. In any case, experimentation (as described in the clone
command above) shows that this patch is a net improvement.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/index-pack.c