Hi, I have a few questions regarding mapped_region. 1. first of all, is mapped_region::flush() safe to use? on linux it is implemented as msync(MS_SYNC) which seems fine, but on windows it uses FlushViewOfFile alone, which IIUC does not flush the changes to disk. MSDN: "The FlushViewOfFile function [...] does not wait to return until the changes are flushed from the underlying hardware disk cache and physically written to disk. To flush all the dirty pages plus the metadata for the file and ensure that they are physically written to disk, call FlushViewOfFile and then call the FlushFileBuffers function." I'm not sure if they really mean "hardware disk cache", since no sync or flush function can entirely make sure of that. but FlushFileBuffers is documented to flush operating system buffers. and the quote above says a call to FlushFileBuffers is necessary. 2. can the mapped memory be accessed while another thread is calling flush()? does that affect the flushing? it is still required that all data that was written to the mapped region at the point of the flush() call is written to disk when it returns. Interprocess' documentation doesn't say anything about that and I can't seem to find any information about that on the underlying functions mmap/FlushViewOfFile either. and 3, not entirely boost related: I get some strange performance results using mapped_region::flush() on linux (not tested on windows so far). I already reduced the flush() calls to a minimum but I still get better performance in many cases using my own filebuf implementation that performs paging without hardware support, using a std::filebuf. using std::filebuf shouldn't be faster than hardware file mapping. when I call flush() relatively frequently that in itself drives performance down, but when I call it less frequently it blocks for noticeable amounts of time. (thus, question 2) do the offset/size arguments to mapped_region::flush() affect performance? I could track what pages are changed, but I was under the assumption the OS already does that. Thanks
Stefan Strasser escribió:
Hi,
I have a few questions regarding mapped_region.
1. first of all, is mapped_region::flush() safe to use?
on linux it is implemented as msync(MS_SYNC) which seems fine, but on windows it uses FlushViewOfFile alone, which IIUC does not flush the changes to disk.
Thanks for the report. Maybe two flush version should be provided, flush() and async_flush(), each one with different guarantees.
2. can the mapped memory be accessed while another thread is calling flush()? does that affect the flushing? it is still required that all data that was written to the mapped region at the point of the flush() call is written to disk when it returns. Interprocess' documentation doesn't say anything about that and I can't seem to find any information about that on the underlying functions mmap/FlushViewOfFile either.
I really don't know. If underlying functions say nothing about it Interprocess can't say much more, but the OS should guarantee memory consistency even in the presence of a flush since the OS flushes the memory without an explicit flush call, just like it flushes its file buffers without user intervention.
and 3, not entirely boost related: I get some strange performance results using mapped_region::flush() on linux (not tested on windows so far). I already reduced the flush() calls to a minimum but I still get better performance in many cases using my own filebuf implementation that performs paging without hardware support, using a std::filebuf.
It seems strange. Maybe shared mapping is slower than private mapping, but I can only speculate.
do the offset/size arguments to mapped_region::flush() affect performance? I could track what pages are changed, but I was under the assumption the OS already does that.
In theory , if the offset is not multiple of the page size you get memory overhead (and additional page flushes), because the OS requires aligned pages and mapped_region fixes that for you, but nothing more than that. If offset/size is page-aligned, it should have no impact. Best, Ion
thanks for your reply. Am Thursday 10 December 2009 08:29:07 schrieb Ion Gaztañaga:
on linux it is implemented as msync(MS_SYNC) which seems fine, but on windows it uses FlushViewOfFile alone, which IIUC does not flush the changes to disk.
Thanks for the report. Maybe two flush version should be provided, flush() and async_flush(), each one with different guarantees.
or rename them entirely. there is a lot of confusion what flush/sync means. in POSIX, flush is flushing internal buffers to the operating system, and sync is synchronizing OS buffers with physical storage. in C++ iostreams, the function that flushes internal buffers is called pubsync(), while in boost iostreams it's called flush. and in interprocess flush() is synchronizing with physical storage (on linux) using msync(). that's not a highlight of c++ and boost in general, I think I'll have to use platform specific code for file and directory access, just to be able to call POSIX fsync() and fdatasync(). neither iostreams/boost iostreams nor boost.filesystem seem to provide that functionality.
2. can the mapped memory be accessed while another thread is calling flush()? does that affect the flushing? it is still required that all data that was written to the mapped region at the point of the flush() call is written to disk when it returns. Interprocess' documentation doesn't say anything about that and I can't seem to find any information about that on the underlying functions mmap/FlushViewOfFile either.
I really don't know. If underlying functions say nothing about it Interprocess can't say much more, but the OS should guarantee memory consistency even in the presence of a flush since the OS flushes the memory without an explicit flush call, just like it flushes its file buffers without user intervention.
yes, but a flush like that has the goal to get some free memory. so it could e.g. refrain from flushing a page that was changed since the other thread started flush(), which is not what you want when your goal is to get the data to disk (if it contains the concurrent modifications or not doesn't matter). but I don't know either.
do the offset/size arguments to mapped_region::flush() affect performance? I could track what pages are changed, but I was under the assumption the OS already does that.
In theory , if the offset is not multiple of the page size you get memory overhead (and additional page flushes), because the OS requires aligned pages and mapped_region fixes that for you, but nothing more than that. If offset/size is page-aligned, it should have no impact.
I'm not using offset/size at all. the whole region is supposed to be flushed. I could track what pages got changed myself though, but I had the assumption that the OS already must have a list of dirty pages, so flush(offset,size) can't be faster than flush(). is that not the case?
participants (2)
-
Ion Gaztañaga
-
Stefan Strasser