4 ms·
Yes, the test is sort of a strange one because the read test is reading directly in to the final destination wheras mmap is not and doing a redundant copy inste
by scaramanga 6y ago
Yes, the test is sort of a strange one because the read test is reading directly in to the final destination wheras mmap is not and doing a redundant copy instead. So it's not your typical "eliminate a copy and go faster" usage of mmap.
What it actually seems to be comparing is whether its faster if the copy happens in the kernel, in the read() system call, or whether it's faster in userspace.
The results are puzzling because I would expect the kernel to be faster since it would incur no page-faults to access the pages from page cache since those ought to fall under the page-global mappings, or, at least, be in the kernels linear ram map which use 1GB pages (edit: in either case, not incur faults for demand map/demand load). But maybe that's no longer the case in a post-spectre world?
So I think actually it's a test of "does AVX go enough-faster to outweigh the costs of the extra-pagefaults incurred by copying from a user-space mapping which has not been prefaulted"
Sounds like the answer is yes (which still surprises me). And I expect if they MAP_POPULATE it would pull even further ahead...
- scaramanga 6y agoYes, 1,167 pagefaults for the read() version and 66,704 pagefaults for the mmap() version. With MAP_POPULATE it's back down to 1,167 faults and it goes a bit faster. My libc is using rep/mov, same as the kernel, however. So I can't conclude that AVX memcpy is the win. From the profile of readsyscall version I see this: 42.12% fa [kernel.kallsyms] [k] copy_user_enhanced_fast_string 14.45% fa [kernel.kallsyms] [k] syscall_exit_to_user_mode 11.00% fa [kernel.kallsyms] [k] find_get_entry 6.28% fa [kernel.kallsyms] [k] syscall_return_via_sysret 5.14% fa [kernel.kallsyms] [k] entry_SYSCALL_64 nearly 15% of the time is spent on a single verw instruction. Spectre mitigations. When I reboot with mitigations=off, sure enough, the difference goes away and read() and mmap() perform identically. What OP has discovered is that spectre mitigations make syscalls enough slower than pagefaults that what used to be a slower way to do things is now faster. If you want the mmap version to perform faster when spectre mitigations are off, you need to use MAP_POPULATE.