Mercurial > hg
view tests/test-diff-upgrade.t @ 38732:be4984261611
merge: mark file gets as not thread safe (issue5933)
In default installs, this has the effect of disabling the thread-based
worker on Windows when manifesting files in the working directory. My
measurements have shown that with revlog-based repositories, Mercurial
spends a lot of CPU time in revlog code resolving file data. This ends
up incurring a lot of context switching across threads and slows down
`hg update` operations when going from an empty working directory to
the tip of the repo.
On mozilla-unified (246,351 files) on an i7-6700K (4+4 CPUs):
before: 487s wall
after: 360s wall (equivalent to worker.enabled=false)
cpus=2: 379s wall
Even with only 2 threads, the thread pool is still slower.
The introduction of the thread-based worker (02b36e860e0b) states that
it resulted in a "~50%" speedup for `hg sparse --enable-profile` and
`hg sparse --disable-profile`. This disagrees with my measurement
above. I theorize a few reasons for this:
1) Removal of files from the working directory is I/O - not CPU - bound
and should benefit from a thread pool (unless I/O is insanely fast
and the GIL release is near instantaneous). So tests like `hg sparse
--enable-profile` may exercise deletion throughput and aren't good
benchmarks for worker tasks that are CPU heavy.
2) The patch was authored by someone at Facebook. The results were
likely measured against a repository using remotefilelog. And I
believe that revision retrieval during working directory updates with
remotefilelog will often use a remote store, thus being I/O and not
CPU bound. This probably resulted in an overstated performance gain.
Since there appears to be a need to enable the thread-based worker with
some stores, I've made the flagging of file gets as thread safe
configurable. I've made it experimental because I don't want to formalize
a boolean flag for this option and because this attribute is best
captured against the store implementation. But we don't have a proper
store API for this yet. I'd rather cross this bridge later.
It is possible there are revlog-based repositories that do benefit from
a thread-based worker. I didn't do very comprehensive testing. If there
are, we may want to devise a more proper algorithm for whether to use
the thread-based worker, including possibly config options to limit the
number of threads to use. But until I see evidence that justifies
complexity, simplicity wins.
Differential Revision: https://phab.mercurial-scm.org/D3963
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 18 Jul 2018 09:49:34 -0700 |
parents | 15ddf83fbf84 |
children | 5abc47d4ca6b |
line wrap: on
line source
#require execbit $ cat <<EOF >> $HGRCPATH > [extensions] > autodiff = $TESTDIR/autodiff.py > [diff] > nodates = 1 > EOF $ hg init repo $ cd repo make a combination of new, changed and deleted file $ echo regular > regular $ echo rmregular > rmregular $ $PYTHON -c "open('bintoregular', 'wb').write(b'\0')" $ touch rmempty $ echo exec > exec $ chmod +x exec $ echo rmexec > rmexec $ chmod +x rmexec $ echo setexec > setexec $ echo unsetexec > unsetexec $ chmod +x unsetexec $ echo binary > binary $ $PYTHON -c "open('rmbinary', 'wb').write(b'\0')" $ hg ci -Am addfiles adding binary adding bintoregular adding exec adding regular adding rmbinary adding rmempty adding rmexec adding rmregular adding setexec adding unsetexec $ echo regular >> regular $ echo newregular >> newregular $ rm rmempty $ touch newempty $ rm rmregular $ echo exec >> exec $ echo newexec > newexec $ echo bintoregular > bintoregular $ chmod +x newexec $ rm rmexec $ chmod +x setexec $ chmod -x unsetexec $ $PYTHON -c "open('binary', 'wb').write(b'\0\0')" $ $PYTHON -c "open('newbinary', 'wb').write(b'\0')" $ rm rmbinary $ hg addremove -s 0 adding newbinary adding newempty adding newexec adding newregular removing rmbinary removing rmempty removing rmexec removing rmregular git=no: regular diff for all files $ hg autodiff --git=no diff -r a66d19b9302d binary Binary file binary has changed diff -r a66d19b9302d bintoregular Binary file bintoregular has changed diff -r a66d19b9302d exec --- a/exec +++ b/exec @@ -1,1 +1,2 @@ exec +exec diff -r a66d19b9302d newbinary Binary file newbinary has changed diff -r a66d19b9302d newexec --- /dev/null +++ b/newexec @@ -0,0 +1,1 @@ +newexec diff -r a66d19b9302d newregular --- /dev/null +++ b/newregular @@ -0,0 +1,1 @@ +newregular diff -r a66d19b9302d regular --- a/regular +++ b/regular @@ -1,1 +1,2 @@ regular +regular diff -r a66d19b9302d rmbinary Binary file rmbinary has changed diff -r a66d19b9302d rmexec --- a/rmexec +++ /dev/null @@ -1,1 +0,0 @@ -rmexec diff -r a66d19b9302d rmregular --- a/rmregular +++ /dev/null @@ -1,1 +0,0 @@ -rmregular git=yes: git diff for single regular file $ hg autodiff --git=yes regular diff --git a/regular b/regular --- a/regular +++ b/regular @@ -1,1 +1,2 @@ regular +regular git=auto: regular diff for regular files and non-binary removals $ hg autodiff --git=auto regular newregular rmregular rmexec diff -r a66d19b9302d newregular --- /dev/null +++ b/newregular @@ -0,0 +1,1 @@ +newregular diff -r a66d19b9302d regular --- a/regular +++ b/regular @@ -1,1 +1,2 @@ regular +regular diff -r a66d19b9302d rmexec --- a/rmexec +++ /dev/null @@ -1,1 +0,0 @@ -rmexec diff -r a66d19b9302d rmregular --- a/rmregular +++ /dev/null @@ -1,1 +0,0 @@ -rmregular $ for f in exec newexec setexec unsetexec binary newbinary newempty rmempty rmbinary bintoregular; do > echo > echo '% git=auto: git diff for' $f > hg autodiff --git=auto $f > done % git=auto: git diff for exec diff -r a66d19b9302d exec --- a/exec +++ b/exec @@ -1,1 +1,2 @@ exec +exec % git=auto: git diff for newexec diff --git a/newexec b/newexec new file mode 100755 --- /dev/null +++ b/newexec @@ -0,0 +1,1 @@ +newexec % git=auto: git diff for setexec diff --git a/setexec b/setexec old mode 100644 new mode 100755 % git=auto: git diff for unsetexec diff --git a/unsetexec b/unsetexec old mode 100755 new mode 100644 % git=auto: git diff for binary diff --git a/binary b/binary index a9128c283485202893f5af379dd9beccb6e79486..09f370e38f498a462e1ca0faa724559b6630c04f GIT binary patch literal 2 Jc${Nk0000200961 % git=auto: git diff for newbinary diff --git a/newbinary b/newbinary new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 Ic${MZ000310RR91 % git=auto: git diff for newempty diff --git a/newempty b/newempty new file mode 100644 % git=auto: git diff for rmempty diff --git a/rmempty b/rmempty deleted file mode 100644 % git=auto: git diff for rmbinary diff --git a/rmbinary b/rmbinary deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001 % git=auto: git diff for bintoregular diff --git a/bintoregular b/bintoregular index f76dd238ade08917e6712764a16a22005a50573d..9c42f2b6427d8bf034b7bc23986152dc01bfd3ab GIT binary patch literal 13 Uc$`bh%qz(+N=+}#Ni5<5043uE82|tP git=warn: regular diff with data loss warnings $ hg autodiff --git=warn diff -r a66d19b9302d binary Binary file binary has changed diff -r a66d19b9302d bintoregular Binary file bintoregular has changed diff -r a66d19b9302d exec --- a/exec +++ b/exec @@ -1,1 +1,2 @@ exec +exec diff -r a66d19b9302d newbinary Binary file newbinary has changed diff -r a66d19b9302d newexec --- /dev/null +++ b/newexec @@ -0,0 +1,1 @@ +newexec diff -r a66d19b9302d newregular --- /dev/null +++ b/newregular @@ -0,0 +1,1 @@ +newregular diff -r a66d19b9302d regular --- a/regular +++ b/regular @@ -1,1 +1,2 @@ regular +regular diff -r a66d19b9302d rmbinary Binary file rmbinary has changed diff -r a66d19b9302d rmexec --- a/rmexec +++ /dev/null @@ -1,1 +0,0 @@ -rmexec diff -r a66d19b9302d rmregular --- a/rmregular +++ /dev/null @@ -1,1 +0,0 @@ -rmregular data lost for: binary data lost for: bintoregular data lost for: newbinary data lost for: newempty data lost for: newexec data lost for: rmbinary data lost for: rmempty data lost for: setexec data lost for: unsetexec git=abort: fail on execute bit change $ hg autodiff --git=abort regular setexec abort: losing data for setexec [255] git=abort: succeed on regular file $ hg autodiff --git=abort regular diff -r a66d19b9302d regular --- a/regular +++ b/regular @@ -1,1 +1,2 @@ regular +regular $ cd ..