An old gripe: Reading via mmap stinks
dillon at apollo.backplane.com
Fri Jan 15 02:56:56 UTC 2010
: mmap: 43.400u 9.439s 2:35.19 34.0% 16+184k 0+0io 106994pf+0w
: read: 41.358u 23.799s 2:12.04 49.3% 16+177k 67677+0io 0pf+0w
:Observe, that even though read-ing is quite taxing on the kernel (high
:sys-time), the mmap-ing loses overall -- at least, on an otherwise idle
:system -- because read gets the full throughput of the drive (systat -vm
:shows 100% disk utilization), while pagefaulting gets only about 69%.
:When I last brought this up in 2006, it was "revealed", that read(2)
:uses heuristics to perform a read-ahead. Why can't the pagefaulting-in
:implementation use the same or similar "trickery" was never explained...
Well, the VM system does do read-ahead, but clearly the pipelining
is not working properly because if it were then either the cpu or
the disk would be pegged, and neither is.
It's broken in DFly too. Both FreeBSD and DragonFly use
vnode_pager_generic_getpages() (UFS's ffs_getpages() just calls
the generic) which means (typically) the whole thing devolves into
a UIO_NOCOPY VOP_READ(). The VOP_READ should be doing read-ahead
based on the sequential access heuristic but I already see issues
in both implementations of vnode_pager_generic_getpages() where it
finds a valid page from an earlier read-ahead and stops (failing to
issue any new read-aheads because it fails to issue a new UIO_NOCOPY
This would explain why the performance is not as bad as linux but
is not as good as a properly pipelined case. I'll play with it
some in DFly and I'm sure the FreeBSD folks can fix it in FreeBSD.
More information about the freebsd-stable