Add an option to reduce pagefault when available in Linux

This option instructs the kernel to synchronously load the entire mapped
region into active memory by specifying `MAP_POPULATE` in `mmap`. It will
cause read-ahead on that memory, and then the subsequent accesses to the
memory can proceed without page faults, improving some performance.
This commit is contained in:
hank 2021-06-26 15:06:13 +08:00
parent 076f815cec
commit 9a66d37d4e
4 changed files with 17 additions and 0 deletions

View file

@ -81,6 +81,9 @@ static mi_option_desc_t options[_mi_option_last] =
{ 1, UNINIT, MI_OPTION(page_reset) }, // reset page memory on free
{ 0, UNINIT, MI_OPTION(abandoned_page_reset) },// reset free page memory when a thread terminates
{ 0, UNINIT, MI_OPTION(segment_reset) }, // reset segment memory on free (needs eager commit)
#if defined(__linux__)
{ 0, UNINIT, MI_OPTION(prefault) },
#endif
#if defined(__NetBSD__)
{ 0, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed
#else

View file

@ -362,6 +362,10 @@ static void* mi_unix_mmap(void* addr, size_t size, size_t try_alignment, int pro
#define MAP_NORESERVE 0
#endif
int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
#if defined(__linux__)
if (mi_option_get(mi_option_prefault))
flags = flags | MAP_POPULATE;
#endif
int fd = -1;
#if defined(MAP_ALIGNED) // BSD
if (try_alignment > 0) {
@ -392,6 +396,9 @@ static void* mi_unix_mmap(void* addr, size_t size, size_t try_alignment, int pro
}
else {
int lflags = flags & ~MAP_NORESERVE; // using NORESERVE on huge pages seems to fail on Linux
#if defined(__linux__)
lflags = lflags & ~MAP_POPULATE; // don't use MAP_POPULATE on huge pages
#endif
int lfd = fd;
#ifdef MAP_ALIGNED_SUPER
lflags |= MAP_ALIGNED_SUPER;