2013-03-30 2 views
8

У меня есть несколько вопросов о буферах и пулах памяти, на которые я хотел бы ответить.Пулы памяти и буферы C++

Скажем, у меня есть сервер, отправляющий и принимающий ~ 50-100 + msg/second. Все msgs бывают разных размеров. Как бы вы сделали это, чтобы сделать все возможное из управления памятью здесь? Мой первоначальный план с использованием фиксированного размера узлов буфера, и объединить их, что-то вроде:

struct buffer{ 
    uint8_t data[512]; 
    uint32_t end; 
    buffer* next; 
} 
buffer* b = pool_get_new_buffer(); 

Так что, когда тзд отправляется, я создать один или несколько буферов в зависимости от размера и соединить их вместе. Таким образом, я не боюсь фрагментации в пуле. (или это по крайней мере то, что я думаю). Но на небольшом msg, это пустая трата пространства.

Но, читая все больше и проверяя код в Интернете, похоже, что никто не использует этот подход вообще. Итак, что было бы лучшим подходом? Выделение памяти из пула в зависимости от размера msg?

EDIT: Так что же после этого может быть более неумелое сравнение различных подходов.

Если я использую подход с привязанным буфером, я предполагаю, что я сохраню фрагментацию на самом низком уровне, но, с другой стороны, я бы предположил, что выполнение memcpy для каждого буфера в цепочке также будет стоить. Но опять же, выделение достаточно большого буфера и выполнение одной memcpy должно иметь свои недостатки, даже если большинство людей выбирают этот подход в любом случае.

+0

Ваша идея хорошая. Вам просто нужно [расширить его] (http://en.wikipedia.org/wiki/Buddy_memory_allocation). Ваши требования выглядят как [общий распределитель] (http://g.oswego.edu/dl/html/malloc.html). Или, возможно, распределитель [SLAB] (http://en.wikipedia.org/wiki/Slab_allocation), если вам нужна инициализация памяти? –

+0

Это не слишком популярно, поскольку Linux и BSD уже имеют довольно хорошие распределители. Распределитель по умолчанию Windows довольно ужасен, но с MSVC2010 они поставляют довольно хороший продукт как часть CRM параллелизма. Обратите внимание, что схема, о которой вы упоминали, в значительной степени использует один и тот же Linux и BSD для сокетов. –

+0

Но почему он не популярен? потому что его сложнее реализовать? или потому, что вы так много не добились этого? Было бы неплохо узнать более конкретно, почему один метод предпочтительнее другого. – user2010820

ответ

1

Как насчет наличия одного буфера, скажем, 0,5/1 МБ. Это, очевидно, зависит от целевой ОС/устройства и, возможно, от вашего максимального размера сообщения. Кроме того, ваш сервер включает размер пакета. Предполагая, что ваш пакет не превышает один размер буфера, вы можете загружать данные в буфер, обрабатывать его, а затем пометить память как доступную. Я использовал этот подход для отдельных клиент-серверных приложений.

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