Существует ли пользовательский шаблон проектирования распределителя памяти, который не хранит метаданные в своих распределениях?
По сути, мне нужен пул памяти для быстрого выделения небольших объектов. В идеале я хотел бы заменить выделения как на хосте, так и для памяти, выделенной на графических процессорах, на cudaMalloc. Я могу написать свое собственное, и я сделаю это, если понадобится, но я бы не отказался от замены одной из надежных реализаций с открытым исходным кодом.
Единственная проблема заключается в том, что с cudaMalloc пул памяти не может касаться выделенной памяти. Насколько я понимаю, многие (все?) Из общих распределителей памяти, таких как в заголовке, хранят небольшое количество метаданных в выделенных данных. Поэтому они не будут работать.
Кто-нибудь знает о распределителе памяти, для которого это не так?
2 ответа
Если все ваши небольшие распределения имеют одинаковый размер или имеют разумную верхнюю границу, тогда хорошим выбором будет распределитель пула фиксированного размера.
Идея состоит в том, что распределитель захватывает большой блок с помощью системного вызова, а затем управляет собственным свободным списком блоков фиксированного размера внутри большого блока. Распределение так же просто, как взять блок во главе свободного списка. Распределение ресурсов немного сложнее, но может быть реализовано различными способами в зависимости от ваших требований.
Это достаточно просто, чтобы написать свой собственный, или если вы используете распределитель фиксированного размера Google C++, вы можете найти ряд хороших реализаций, включая boost::pool
Любой распределитель должен где-то хранить метаданные. Конечно, когда потребность в выделении становится проще, количество метаданных будет уменьшаться.
Я думаю, нормальный распределитель фиксированного размера все еще будет доставлять вам неприятности, когда я правильно понимаю вашу проблему. У вас действительно особые аппаратные ограничения, насколько я вижу.
Конечно, вы можете использовать фиксированный распределитель пула, который не предлагает освободить отдельные выделения, а только освободить весь пул. Таким образом, необходимость хранить метаданные внутри выделенной памяти будет устранена.
Конечно, вы всегда можете реализовать распределитель, который хранит метаданные вне выделенной области, используя другую область памяти. Но большинство библиотек хранят метаданные в выделенной области, потому что это наиболее удобно для обычных архитектур.
Таким образом, лучшим предположением будет найти фиксированный распределитель пула, который либо не предлагает функциональности для освобождения отдельных выделений, либо где вы просто не можете использовать эту функцию (и, следовательно, распределитель не хранит никакой). Это, конечно, единственный вариант, когда вам будет хорошо, всегда высвобождать целые пулы памяти вместо отдельных выделений (что, между прочим, является хорошей мерой предосторожности против утечек памяти, если это применимо).
Конечно, другой альтернативой может быть реализация собственного распределителя, возможно, на основе простого распределителя, который использует как можно более простые метаданные.