2010-11-12 3 views
11

Я ищу окончательный ответ (если он действительно существует) о том, сколько памяти должно быть выделено при создании статических кусков общей памяти через boost::interprocess's managed_shared_memory. Даже official examples, кажется, выделяют arbitrarily large куски памяти.Сколько памяти следует использовать «managed_shared_memory»? (boost)

Рассмотрим следующую структуру:

// Example: simple struct with two 4-byte fields 
struct Point2D { 
    int x, y; 
}; 

Моя первая реакция является то, что необходимый размер будет 8 байт, или sizeof(Point2D). Это терпит неудачу, когда я пытаюсь построить объект, давая мне seg-faults во время выполнения.

// BAD: 8 bytes is nowhere near enough memory allocated. 
managed_shared_memory segment(create_only, "My shared memory", sizeof(Point2D)); 

Какая операция чтения/записи вызывает seg-faults? Операции стека? Временно распределяется в пределах segment.construct()? Сколько накладных расходов необходимо при распределении разделяемой памяти?

Путем проб и ошибок я обнаружил, что умножение размера на 4 может работать для вышеуказанной структуры, но разваливается, когда я начинаю добавлять дополнительные поля к моему struct. Итак, это пахнет плохим взломом.

Некоторые могут утверждать, что «память дешевая» на современном ПК, но я не согласен с этой философией и не люблю выделять больше, чем мне нужно, если я могу ее избежать. Вчера я выкопал документы Boost и не нашел никаких рекомендаций. Вот, чтобы узнать что-то новое сегодня!

+1

Люди могут не согласиться со мной здесь, но я никогда в жизни не кодировал по строкам «память дешевая». Покупка памяти не обязательно стоит дорого по сравнению с тем, как она была раньше, но она очень похожа на деньги. Чем больше у вас есть, тем больше вы тратите. Каждое обновление памяти, которое я купил для своего компьютера, я быстро освоил, что могу «запустить больше вещей». Я всегда старался кодировать консервативно в этом отношении, потому что это не обязательно дешево * для моего приложения *. Во всяком случае, только мой 2c на этом :) –

+0

Я согласен на 100%! И это все ** причина, по которой я задаю этот вопрос. Я только бросил этот комментарий там, чтобы отговорить любого, кто сказал: «Кто заботится, просто выделите 1k и сделайте с ним». Я постараюсь сделать это более ясным в этом посте. –

+0

Ah ok :) «Некоторые могут спорить» намного лучше! –

ответ

8

Из this paragraph документации:

Алгоритм памяти представляет собой объект, который помещаются в первых байтах разделяемой памяти/памяти отображается файл сегмента.

Компоновка сегмента памяти:

____________ __________ ____________________________________________ 
|   |   |           | 
| memory | reserved | The memory algorithm will return portions | 
| algorithm |   | of the rest of the segment.    | 
|____________|__________|____________________________________________| 

Библиотека имеет дополнительную память над головой, сидя в начале сегмента, таким образом, занимая несколько байт вашего требуемого размера. По this post и this post, это точное число дополнительных байтов не может быть определена:

Вы не можете вычислить его, потому что есть память bookeeping распределение и проблемы фрагментации, которые изменяются в выполнения в зависимости от вашего распределения/снятие паттерна. И разделяемой памяти выделяется страниц по ОС (4K на Linux 64k на окна), так что любое распределение будет на практике выделено закруглены страницы :

managed_shared_memory segment(create_only, "name", 20); 

будет тратить ту же память, :

managed_shared_memory segment(create_only, "name", 4096); 
+0

Хорошая работа, чтобы найти старую почту; Я искал довольно долго и подошел сухой. Итак, «действительно» вы имеете в виду, что ** нет конкретного ответа? ** Это то, что я получаю от ответа Иона Газтаньяги ... Кроме того, спасибо за эту ссылку на документы Boost. Карта памяти ASCII art помогает, хотя мне не повезло в программном определении «алгоритм памяти» + «зарезервировано». Но в конечном счете, это спорный момент, так как моя фактическая реализация хранит 5-10 экземпляров структуры (также упоминается Gaztañaga). Тем не менее, это похоже на правильный вопрос, даже если это в основном «академический». –

+0

Ah, * там * отправляем. Я знал, что размер страницы ОС должен быть соответствующей деталью; приведенная выше цитата подтверждает мои подозрения. Похоже, что «лучшее предположение» придется делать. Еще раз спасибо. –

2

Нечто подобное использование произведения размер страницы OS'es памяти. В моем случае это работает ..

off_t size = sizeof(class1) + (sizeof(class2) * 3); 
// round up to the OS page size. 
long page_size = sysconf(_SC_PAGE_SIZE); 
size = ((size/page_size) + (size % page_size ? 1 : 0)) * page_size; 

Использование boost :: managed_shared_memory позволяет создавать объекты в полученном пространстве. Что-то вроде ....

shared_memory_object::remove(m_name.c_str()); 
m_shared.reset(new managed_shared_memory(create_only, "myspace", size)); 
m_class1 = m_shared->construct<class1>("class1")(); 
m_class2 = m_shared->construct<class2>("class2")[3](); 
+0

+1 Мне нравится идея округления до размера страницы системы. Тем не менее, похоже, что мы создаем ** произвольное количество отступов **. В этом случае «3» - три раза «sizeof (class2)». Я прав? С тех пор я перешел к другим проектам, но меня все еще интересует лучший способ распределения общей памяти с наименьшим количеством отходов. –

+0

Я не могу все равно обойти, используя размер страницы для области общей памяти. (Исправлена ​​ошибка во втором бите кода.) Однако вы можете сделать тип субраспределения, которое я использовал во втором бите кода внутри области общей памяти. см. Http://en.highscore.de/cpp/boost/interprocesscommunication.html#interprocesscommunication_managed_shared_memory дает довольно хорошее представление о многих способах, которыми может выполняться подсегмент. Мне бы лучше изучить этот редактор, чтобы я мог более четко связывать * вздох * – lprent

Смежные вопросы