Various performance improvements on Windows - #175
Conversation
|
Hey, thanks for the PR! Could you elaborate a bit on the intended use case for this? |
|
We use mmap on windows and map a lot (thousands) files as read only. Easiest way was to add a new public function and not modify "map()" but you tell me what you feel is best |
|
Right, thanks for the explanation! Good to know it's really about the overhead of the syscalls :) Since this new function still returns a That feels less intrusive than adding another mapping function, plus it can be honored by both |
|
Gotcha, i'll implement it that way |
By default, creating a file-backed mapping on Windows issues up to two extra CreateFileMappingW calls to probe whether the handle supports write and/or execute access, so that the section is created with the widest protection the handle allows and the view can later be transitioned with make_mut()/make_exec(). A side effect is that mapping a file read-only through a writable handle still creates a writable section on it. With MmapOptions::no_probe_handle() set, the section and view are created in a single call each, with exactly the protection the mapping type requires (e.g. PAGE_READONLY/FILE_MAP_READ for map()). This guarantees a read-only mapping never creates a writable section, at the cost that transitioning the returned mapping to a wider protection fails.
GetSystemInfo is implemented as two NtQuerySystemInformation system calls, and allocation_granularity() is called at least twice over a mapping's lifetime (creation and unmapping on drop), plus once per flush. Cache the value in a static, the same way page_size() already is on unix; the racy initialization is benign since GetSystemInfo is idempotent and the granularity is constant for the lifetime of the system.
|
@de-vri-es Done, i've also added another performance improvement in the |
|
Looks good! Thanks for the changes. I've pushed one commit to disable the clippy lint that was triggering. Will merge once CI is green :) |
Various performance improvements on Windows:
mmap2 performs extra checks on the file handle (2 extra CreateFileMapping) to check if the mapping can be "upgraded" to write or execute.
When requesting a pure readonly mapping, those extra checks are useless.
So add a
no_probe_handlefunction toMmapOptions(a lano_reserve_swapon Unix) to avoid probing those handlesWhen creating a new mapping or dropping it,
allocation_granularityis queried, which leads to callingGetSystemInfothat performs at least 2 syscalls (see screenshot, 1 more syscall inGetSystemInfoInternal) .Cache the result to avoid getting the same information each time (stored like
page_sizeon Unix)Quick benchmark: around 30% performance gain (27 -> 17 us for mapping a file + destroying the handle)