Anthony
Anthony

Reputation: 12387

Sharing small data using Windows shared memory

I'm looking for advice and suggestions for storing small amounts of data (only a few bytes) in a shared memory segment on Windows.

Right now, whenever we map shared memory, we round the mapping size up to the nearest 4KB so we get a multiple of pages mapped.

mem_size = ((mem_size + 4095) / 4096) * 4096;

However, I want to map enough memory to share a named integer between processes. Or more specifically, many differently-named integers between processes. About a thousand integers, all with different names and each one mapped by one or more processes is what I'm looking at.

I don't want to round 4 bytes up to 4KB because this would be a huge waste. After creating a thousand or so of these, I would have used about a thousand pages when I only needed one.

But I am worried about the overhead of creating a named memory segment for just 4 bytes. Will the OS be "reasonable" enough to try and fit the different mappings onto the same page where possible? (There are no guarantees, I know). Or will this quickly blow out?

I had considered mapping one huge block of memory, but the individual integers still need to be referred to by name. Maintaining a hash table inside shared memory seems like I'd just be duplicating the work of the OS.

Is there an alternative to the CreateFileMapping/OpenFileMapping and MapViewOfFile technique that would be more suited to sharing very small amounts of data between processes? Or am I worrying over nothing?

Upvotes: 4

Views: 714

Answers (2)

JackCColeman
JackCColeman

Reputation: 3807

You could do this in 8K. The first 4k block is a binary table (or a hash table) for the integer name and its offset in the second 4k block. When adding a new name, you will need to serialize, and when retrieving a name/offset, block on that serialization.

After a process has retrieved its name/offset it can then go directly to the second block and avoid any serialization! This will be a logic path that is taken more than 90% (probably) of the time. Thus your code should run very efficiently with minimal overhead.

The second 4k block will hold 1,000 ints (in windows anyway!). Each integer would NOT affect the others, so this design is "thread safe". However, if the processes do a lot (where a lot is every process updates about every 1ms, so that two processes are always in contention to write to the file) of updating to this common file, and the complete file has to be serialized (rather than implicitly because no two processes share the same integer name) when updating in place then you could end-up with a bottleneck.

the following link: http://msdn.microsoft.com/en-us/library/aa366801%28v=vs.85%29.aspx describes how to update the shared memory. If each process has its own integer "slot" then there shouldn't be any contention.

I don't think a name tree or hash table is duplicating the OS.

Finally, this seems like a medium skill project and should be relatively easy to maintain!

Upvotes: 4

youdontneedtothankme
youdontneedtothankme

Reputation: 672

A shared memory segment on x86 processeors can't be smaller than 4096 bytes. Shared memory is handled by the mmu on the processor, which organizes everything in 4096 bytes large pages.

Upvotes: 1

Related Questions