4 ms·
I don't see the problem here. The code you quote is correct and guaranteed to allocate the minimum amount of memory for which the hardware can support the reque
by olooney 8y ago
I don't see the problem here. The code you quote is correct and guaranteed to allocate the minimum amount of memory for which the hardware can support the requested functionality.
It passed sizeof(std::atomic<uint64_t>) as the length parameter and mmap() decided to give us a larger page (which may or may not be 4k) for its own very good reasons, namely that the overhead of keeping track of hyper-granular memory pages would cost more than it would save.
For a program that needs at least one shared counter, it's not possible to allocate less than one page of shared memory, regardless of if its implemented in C++, C, or whatever language -- it's a hardware level decision. If MMU designers could still provide 512 or smaller pages with the same performance as 4k pages they would certainly do so. Nor is it reasonable to keep track of memory flags like MAP_SHARED at a more granular level than a single page.
If the program did need more than one shared counter, it could instead use something like std::array<std::atomic<uint64_t>, 512>. In other words, there's no reason why it would have to allocate 4k for every shared counter -- there's zero inherent overhead. It appears as if this particular program only needed 8 bytes, request 8 bytes, and had its request satisfied in the best way the hardware could allow.
- glandium 8y agoWell, there's not a lot of context to say whether there are more shared counters. That said, I overlooked the MAP_SHARED, and the code actually got itself in non-portable land. Not all atomics are actually atomics. IIRC, at least ARM doesn't have 64-bits atomics, and using atomics on such platforms means using locks. Which are very likely to not work properly in shared memory.