2

I am keeping two objects in shared memory, one of them is a class which is :

class GlobalObj
{
public: 
    unsigned int counter;
    unsigned int label;
    bool isExist;

    Globals(void){}
    ~Globals(void){};
};

And the other one is a boost::multi_index_container which holds that type objects:

class TestObj
{   
public:
    long id;
    unsigned _int64 track1; 
    unsigned _int64 track2;
    int label;


    MetaData(void){};
    ~MetaData(void){};
};

So when I am constructing the shared memory I calculate the size in this way:

// TEST_CONTAINER_SIZE is a constant which is the 
// maximum number of record that multi_index container will keep
size_t containerSize = TEST_CONTAINER_SIZE * sizeof(TestObj);

// create shared memory         
managed_shared_memory segment(create_only,"SharedMemory", containerSize + sizeof(GlobalObj));

So when I set TEST_CONTAINER_SIZE = 10000; I expect that I can insert 10000 TestObj into the multi_index container in shared memory. But when I run the program it fires an exception related with the shared memory size in 3071th item.

Is there any overhead of multi_index container itself, or am I missing any other thing while I am calculating the size of shared memory?

Thanks.

EDIT:

So in my current implementation my multi_index container and allocation looks like this:

typedef multi_index_container<
    TestObj, 
        indexed_by<    
            ordered_unique<member<TestObj, long, &TestObj::id> >,
            ordered_non_unique< member<TestObj, unsigned _int64, &TestObj::track1> >
        >, 
        boost::interprocess::managed_shared_memory::allocator<TestObj>::type
> ContainerType;


segment = new managed_shared_memory(open_only, "SharedMemory");

DataContainer = segment->construct<ContainerType>
        ("DataContainer")                      //Container's name in shared memory
        ( ContainerType::ctor_args_list()
        , segment->get_allocator<TestObj>());    

So since I know how many items there will be in my container what is the most efficient and stable way to allocate it?

Vecihi
  • 261
  • 4
  • 12

2 Answers2

0

This is entirely implementation dependant, you can't assume anything about the container's size. You probably want to use a custom allocators with your multi_index container.

Paul Evans
  • 27,315
  • 3
  • 37
  • 54
  • I don't see how it could work if he weren't using custom allocators from boost IPC. In fact, then he would not run out of shared memory, at all :) – sehe Apr 24 '14 at 11:40
0

There is a lot of overhead for managing the shared memory segment.

You should really let the allocator figure it out, or allocate a contiguous range of these objects from the segment, so you can accurately predict the amount of memory required.

In this answer I've contrasted a number of allocation overheads with managed_shared_memory:

A picture says a thousand words:

enter image description here

As you can see, the amount of memory remaining highly depends on the way in which you manage the allocations.

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Thanks for the answer. Please see my edit. And could you please tell me how to implement flat_map_reserved way? – Vecihi Apr 24 '14 at 12:01
  • @Vecihi I think the code should be in the linked answer. I make it a point to always include the running code. Just use the second `#if` branch (as shown in the code) – sehe Apr 24 '14 at 12:02
  • Ok I will try that one and inform. Thanks. – Vecihi Apr 24 '14 at 12:18
  • Note that you can use the `get_free_memory()` call that I used to detect effective memory usage. Be warned that the usage may not be identical each time, because it depends on the usage patterns too (fragmentation). That's why `reserve`-ing the memory helped. – sehe Apr 24 '14 at 13:23