Mercurial > public > mercurial-scm > hg-stable
diff mercurial/util.py @ 51800:b619ba39d10a
mmap: populate mapping in a background thread
When possible, we populate the memory mapping in a second thread. The mmap
population does not only read the data from disk to memory. It also actually
fill the memory mapping between process memory address and the physical memory
used by the file system cache containing the mmap'ed data.
Doing so buy back the slowdown from pre-population when it matters. When most
data is accessed, only a few page fault will occurs, while the background thread
fill the memory controller. When few data is accessed, the non-blocking mmap
won't have to wait for all data to be populated.
Here is a few example of improvement seen in benchmark around unbundle and push:
### data-env-vars.name = netbeans-2018-08-01-zstd-sparse-revlog
# benchmark.name = hg.command.unbundle
# benchmark.variants.issue6528 = disabled
# benchmark.variants.reuse-external-delta-parent = yes
# benchmark.variants.revs = any-100-extra-rev
before: 0.758101
after: 0.732129 (-3.43%, -0.03)
## data-env-vars.name = mozilla-try-2019-02-18-zstd-sparse-revlog
before: 1.519941
after: 1.503473 (-1.08%, -0.02)
### data-env-vars.name = mozilla-try-2019-02-18-zstd-sparse-revlog
# benchmark.name = hg.command.push
# bin-env-vars.hg.flavor = default
# benchmark.variants.issue6528 = disabled
# benchmark.variants.protocol = ssh
# benchmark.variants.reuse-external-delta-parent = yes
# benchmark.variants.revs = any-1-extra-rev
before: 4.801442
after: 4.695810 (-1.46%, -0.07)
# benchmark.variants.revs = any-100-extra-rev
before: 4.848596
after: 4.794075 (-1.12%, -0.05)
# bin-env-vars.hg.flavor = rust
# benchmark.variants.revs = any-1-extra-rev
before: 4.818410
after: 4.700053 (-2.46%, -0.12)
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 09 Jul 2024 20:08:48 +0200 |
parents | 92845af308b4 |
children | 62806be5cbda |
line wrap: on
line diff
--- a/mercurial/util.py Thu Jul 25 14:40:38 2024 -0400 +++ b/mercurial/util.py Tue Jul 09 20:08:48 2024 +0200 @@ -451,7 +451,9 @@ def has_mmap_populate(): - return hasattr(mmap, 'MAP_POPULATE') + return hasattr(osutil, "background_mmap_populate") or hasattr( + mmap, 'MAP_POPULATE' + ) def mmapread(fp, size=None, pre_populate=True): @@ -475,10 +477,13 @@ size = 0 fd = getattr(fp, 'fileno', lambda: fp)() flags = mmap.MAP_PRIVATE - if pre_populate: + bg_populate = hasattr(osutil, "background_mmap_populate") + if pre_populate and not bg_populate: flags |= getattr(mmap, 'MAP_POPULATE', 0) try: m = mmap.mmap(fd, size, flags=flags, prot=mmap.PROT_READ) + if pre_populate and bg_populate: + osutil.background_mmap_populate(m) return m except ValueError: # Empty files cannot be mmapped, but mmapread should still work. Check