Questions about mmap and shm_open


 
Thread Tools Search this Thread
Top Forums Programming Questions about mmap and shm_open
# 1  
Old 12-02-2009
Questions about mmap and shm_open

Hello everyone! I have some questions about mmap and shm_open, and thanks in advance for helping!

I'm involved in a project that several independent processes need to access a huge file (about 3.5G) in random pattern. The access frequency is high, so fseek and fread might be a bad choice for performance consider. My requirements are: 1) All file data are better to be in memory before any process accesses. 2) Also, assume the file is immutable, it is better to have only one copy of the data in memory in all time.

I can come up two different approaches. Approach One, every process mmap the file with MAP_SHARED flag. As mmap turns the file data into memory mapping, the file data accesses can be considered as memory accesses. However, the first time a specific location of the memory mapping is read, the kernel still goes to read the file, thus have some performance issue.

Approach Two, start a "host" process before all other processes, which creates a shared memory objects using shm_open and copy the file data to it. Subsequent process mmap the shm with MAP_SHARED flag. Since all data are available in memory, this approach should have better performance and scalability.

I did some comparisons between theses two plus the direct file operations (name Approach Three, without O_SYNC flag), and the results confuse me a lot (sorry for omitting the result data, I want to keep the thread clean to read). Note that the Approach Two result does not include the object creation time.

For sequential read, usually Approach Three is the fastest, and Approach Two is the slowest. Although the difference between three is tiny, it shows that the access through mmap + shm has significant overhead.

For random read (each read 192 bytes), Approach Two is often to best, and Approach Three is very bad as expected. However, Approach One is never far behind, sometimes even better than Approach Two.

Now my questions:
1) Are my experiments enough to show that shm_open has high overhead, which cancels its advantage of copying from memory, not disk?

2) If 1) is true, there is no reason to use shared memory object ever, since it has initialization before use while direct mmap does not. What's the benefit of shm?

3) Obviously, file reading does not require large buffer (this is application specific), which gives it some scalability. Do mmap and mmap + shm_open use a lot of memory? If process A mmap the file, reads some bytes in the mapping area, does kernel copy the bytes to process A's private memory space? Does each process reserves some amount of memory for caching?

4) If the answer to 3) is false, what is the cost that mmap pays in exchange of much better performance? AFAIK, there is no free lunch.

5) If the answer to 3) is true, then each process still maintains some private copy for their own, which threatens the scalability. Then the shared memory object is not really singleton. Is there really singleton implementation in Linux? I know in Windows, there are APIs ReadProcessMemory and WriteProcessMemory that allows unrelated processes to read others' memory space.

Please correct me if I'm wrong. I really want to know how to implement this cool thing. Thanks!
# 2  
Old 12-03-2009
How much RAM do you have? If you don't have enough physical RAM, even if you copy the data into a shared memory buffer it will just get paged out anyway. So make sure you have enough RAM. Depending on what you're doing, that's probably mean you need at least 8 GB. At least.

Another option is to use open()/pread() if you're reading 192-byte chunks. Using fseek()/fread() is going to be horrible because each pair of calls actually causes 8 kB to be read (most likely) because of the buffering being done. You can change the buffer size using (IIRC...) setbuf() and/or setvbuf() to better match your IO pattern, though. If you have enough RAM on the box, the data in the file will tend to be cached anyway, so any steps you take to copy the data into memory won't really help much.

And do NOT use O_SYNC. That gets you nothing.

Another thing to consider is that mmap() will NOT actually put data into memory until you actually try to read it and the data is page-faulted in from disk. You can use mlock() to lock the mmap()'d file into memory, and to really see how fast you can go, you can actually read at least one byte from each mapped paged when you mmap() the file to force each page to be read in from disk before you start processing.

And FWIW, the best mmap() options are probably to open() the file in O_RDONLY mode, and use read-only permissions on the memory mapping itself, along with the MAP_SHARED option. Hopefully in that case each process will then be able to map the same physical RAM into its virtual address space and you'll only wind up with one copy of the file in physical RAM. You can observe the mmap() flags used when processes mapped shared object executable code to see how this works.
# 3  
Old 12-03-2009
Quote:
Originally Posted by CrendKing
I'm involved in a project that several independent processes need to access a huge file (about 3.5G) in random pattern. The access frequency is high, so fseek and fread might be a bad choice for performance consider. My requirements are: 1) All file data are better to be in memory before any process accesses. 2) Also, assume the file is immutable, it is better to have only one copy of the data in memory in all time.

I can come up two different approaches. Approach One, every process mmap the file with MAP_SHARED flag. As mmap turns the file data into memory mapping, the file data accesses can be considered as memory accesses. However, the first time a specific location of the memory mapping is read, the kernel still goes to read the file, thus have some performance issue.
There's no avoiding the fact that data needs to be read from disk sometime. If you know certain specific bits of it that will be accessed more frequently than the rest, you might streamline that a bit by locking those into memory in advance; you could also warn the kernel before you use it with posix_madvise if your system has it.
Quote:
Approach Two, start a "host" process before all other processes, which creates a shared memory objects using shm_open and copy the file data to it. Subsequent process mmap the shm with MAP_SHARED flag. Since all data are available in memory, this approach should have better performance and scalability.
I don't see how this would be an improvement. If you have enough memory, your kernel can cache it in the first place without all this duplication -- triplication, in this case, since your kernel will be trying to cache it despite you creating your own caches.
Quote:
For sequential read, usually Approach Three is the fastest, and Approach Two is the slowest. Although the difference between three is tiny, it shows that the access through mmap + shm has significant overhead.
Indeed, since you're using double the memory to do more or less the same thing.
Quote:
1) Are my experiments enough to show that shm_open has high overhead, which cancels its advantage of copying from memory, not disk?
It's not that shm_open has high overhead, it's that you're doing more work for little to no gain -- copying from disk cache to memory instead of using cached disk through mmap.
Quote:
4) If the answer to 3) is false, what is the cost that mmap pays in exchange of much better performance? AFAIK, there is no free lunch.
mmap can only deal with memory in blocks of page size -- that is to say, 4K for many systems. The minimum read you can do is therefore 4K. I think this limitation carries into disk cache in general though so it may not be relevant.

Get enough memory and most of what you need will stay in disk cache.
# 4  
Old 12-03-2009
First of all, thank you for answers!

Quote:
Originally Posted by achenle
How much RAM do you have?
16G.

Quote:
Originally Posted by achenle
And FWIW, the best mmap() options are probably to open() the file in O_RDONLY mode, and use read-only permissions on the memory mapping itself, along with the MAP_SHARED option. Hopefully in that case each process will then be able to map the same physical RAM into its virtual address space and you'll only wind up with one copy of the file in physical RAM. You can observe the mmap() flags used when processes mapped shared object executable code to see how this works.
This is exactly what I used. So you mean mmap turns this to happen: multiple unrelated processes shared same physical memory regions. Then is there any way I can measure this kind of sharing? Obviously I cannot tell from the decrement of free memory size. Each process seems reserve some 191 megabytes for Data+Stack size.

Quote:
Originally Posted by Corona688
It's not that shm_open has high overhead, it's that you're doing more work for little to no gain -- copying from disk cache to memory instead of using cached disk through mmap.
For Approach One, data comes from mapped memory region, which eventually comes from disk, or disk cache. For Approach Two, data also comes from mapped memory regions, which eventually comes from the shared memory object created by the "host" process. Therefore I think the only difference is whether disk or disk cache is faster, or shared memory object is faster. My results say they are equal, which I expect not.

-----

My conclusion is, if unrelated processes need to share existing files, always use direct mmap with MAP_SHARED. If unrelated processes need to share memory for maybe IPC purpose, shm_open + mmap could have slightly better performance. Am I correct?
# 5  
Old 12-03-2009
Quote:
Originally Posted by CrendKing
Therefore I think the only difference is whether disk or disk cache is faster, or shared memory object is faster. My results say they are equal, which I expect not.
Well, why shouldn't they be equal? Ignoring the slight overhead of loading your memory segments in the first place, they're both RAM.
# 6  
Old 12-03-2009
I totally understand why disk CACHE = shared memory object. I do not understand why the disk seek time + disk read time = shared memory object for the first time, as the workload is random read. What does mmap internally do to have this significant gain?

Thanks.
# 7  
Old 12-05-2009
I have no idea what you're saying now. Except that, assuming enough memory, it gets read only once. If you want it all to be read in advance before the process begins operating on it, under Linux 2.6.x, mmap has the MAP_POPULATE flag.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. BSD

Mmap source

I'm new to kernels and C, and I am tinkering around trying to understand OpenBSD's secure memory management. I'm stumped on a couple points. I've read up on malloc() which was apparently modified years ago to allocate memory using mmap. First question, that would be this here, right? ... (4 Replies)
Discussion started by: dcicc
4 Replies

2. Emergency UNIX and Linux Support

mmap

I want to know whether this is possile or ever been tried out. I want to obtain a chuck of memory using mmap() I do it so : n = mmap(0, 8000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); And hold on to that memory, when a process requests for memory, some memory is... (2 Replies)
Discussion started by: xerox
2 Replies

3. Programming

mmap

hai, How do we map 'n' number of files into memory by using mmap system call?? Thanks in advance...... (5 Replies)
Discussion started by: andrew.paul
5 Replies

4. Homework & Coursework Questions

mmap

Descriptions: Develop a program that uses mmap() to map a file to memory space. Prepare such a file by yourself and do the follows. <LI class=MsoNormal>Display the content of the file after mapping; <LI class=MsoNormal>Output how many digits included in the file; <LI class=MsoNormal>Replace... (1 Reply)
Discussion started by: gokult
1 Replies

5. Programming

mmap()

how to use mmap() to map a file to memory space. Do you have any simple program???? Because I have to implement lot of concepts into it. (5 Replies)
Discussion started by: gokult
5 Replies

6. UNIX for Dummies Questions & Answers

mmap()

how to use mmap() to map a file to memory space. Do you have any simple program???? Because I have to implement lot of concepts into it. (3 Replies)
Discussion started by: gokult
3 Replies

7. Solaris

mmap() on 64 bit m/c

Dear Experts, i have a problem related to mmap(), when i run my program on sun for 64 bit which is throwing SIGBUS when it encounters mmap() function, what is the reason how to resolve this one, because it is working for 32 bit. with regards, vidya. (2 Replies)
Discussion started by: vin_pll
2 Replies

8. UNIX for Advanced & Expert Users

mmap and select

I'm using select() to monitor multiple file descriptors (inet sockets) in application. But this application must also collaborate with other applications on the same host via shared memory (mmap'ed file) due to performance reasons. How can I become notification that mmaped memory is changed or... (1 Reply)
Discussion started by: Hitori
1 Replies

9. HP-UX

mmap failed

We recently have been seeing the following type of error on our development server. Being somewhat new to HP-UX I was hoping to get some insight. Here is what I have found. I have been doing some research. /usr/lib/dld.sl: Call to mmap() failed - TEXT /u07/mdev/lib/libCLEND.sl... (2 Replies)
Discussion started by: scotbuff
2 Replies

10. Filesystems, Disks and Memory

mmap

Hello. I'm writing some random access i/o software on Solaris 8 using mmap64 to memory map large files (my test file is ~25 GB). The abbreviated code fragment is: fd = open(cbuf,O_RDONLY|O_LARGEFILE); struct stat statbuf; fstat(fd,&statbuf); off_t len =... (0 Replies)
Discussion started by: gusm
0 Replies
Login or Register to Ask a Question