mmap() vs. reading blocks
I heard (read it on the internet somewhere) that
mmap() is faster than sequential IO. Is this correct? If yes then why it is faster?
mmap()is not reading sequentially.
mmap()has to fetch from the disk itself same as
- The mapped area is not sequential - so no DMA (?).
mmap() should actually be slower than
read() from a file? Which of my assumptions above are wrong?
I heard (read it on the internet somewhere) that mmap() is faster than sequential IO. Is this correct? If yes then why it is faster?
Yes - it's typically (and often massively) faster. Reasons below....
1) mmap() is not reading sequentially. 2) mmap() has to fetch from the disk itself same as read() does 3) The mapped area is not sequential - so no DMA (?).
So mmap() should actually be slower than read() from a file? Which of my assumptions above are wrong?
1) is wrong...
mmap() assigns a region of virtual address space corresponding to file content... whenever a page in that address space is accessed, physical RAM is found to back the virtual addresses and the corresponding disk content is faulted into that RAM. So, the order in which reads are done from the disk matches the order of access. It's a "lazy" I/O mechanism. If, for example, you needed to index into a huge hash table that was to be read from disk, then
mmaping the file and starting to do access means the disk I/O is not done sequentially and may therefore result in longer elapsed time until the entire file is read into memory, but while that's happening lookups are succeeding and dependent work can be undertaken, and if parts of the file are never actually needed they're not read (allow for the granuality of disk and memory pages).
2) absolutely true
3) "The mapped area is not sequential" is vague. Memory mapped regions are "contiguous" (sequential) in virtual address space. We've discussed disk I/O being sequential above. Or, are you thinking of something else? Anyway, while pages are being faulted in, they may indeed be transferred using DMA.
Further, there are other reasons why memory mapping tends to outperform usual I/O:
- there's less copying: often library level routines pass data through one or more buffers before it reaches some application-usable location or storage, whereas memory mapping facilitates in-place usage, particularly as:
- memory mapping can simplify the application's parsing job by letting the application treat the entire file content as accessible, rather than worrying about when to read another buffer full
- the application defers more to the OS's wisdom re number of pages that are in physical RAM at any single point in time, effectively sharing a direct-access disk cache with the application
- as well-wisher comments below, "using memory maping you typically use less system calls"