Andy Melnikov (nponeccop) wrote,
Andy Melnikov
nponeccop

Category:

Scoped Resource Pool + Stack Allocator как расширение концепции Apache Pools

Scoped resource pool - это модель полуавтоматического управления ресурсами в С++, средняя между моделью "конструктор-деструктор" и сборкой мусора.

Псевдокод:
{
   pool p;
   void *a = p.allocate(2);
   void *b = p.allocate(3);
}
При смерти пула освобождаются все выделенные в нем ресурсы (в общем случае не только память).

В некотором смысле пул является обобщением scope, автоматического управления памятью в С++ и умных указателей auto_ptr/shared_ptr. В случае автоматического управления памятью грохаются все члены текущего scope или все члены структуры. А в случае пула - все члены пула.

Это дает возможность не следить за тем, чтобы каждый индивидуальный ресурс был освобожден - все выделенные ресурсы будут убиты одним махом при убивании пула.

Пул является в общем случае декоратором нижележащего аллокатора/деаллокатора ресурсов.

Однако такая модель выделения памяти (ресурсы сначала только выделяются, а потом только освобождаются причем все сразу) дает интересные возможности для оптимизации производительности, слегка пожертвовав инкапсуляцией аллокатора и сделав его интерфейс более толстым.

Классические кучи ориентированы на случайное выделение и удаление блоков случайного размера. Boost Pool Library [2] ориентирована на случайное выделение и удаление блоков фиксированного размера. Scoped resource pool же позволяет использовать самый простой и быстрый способ выделения памяти - стек (правда, сегментированный в общем случае).

То есть, большие сегменты стека запрашиваются стековым аллокатором у нижележащего аллокатора сегментов (ниже на 2 уровня чем пул), а новые объекты просто добавляются в конец текущего сегмента и смещается указатель конца сегмента. При переполнении сегмента в список сегментов добавляется новый блок.

При удалении пула и стекового аллокатора могут вызываться в цикле все деструкторы объектов (а могут и не вызываться, в зависимости от потребностей) и освобождаются сегменты путем вызова аллокатора сегментов.

Таким образом, использование стека в сочетании с пулом позволяет:
  1. существенно ускорить операции выделения и освобождения памяти за счет того, что некоторое количество неиспользуемой памяти не освобождается до уничтожения пула;
  2. уменьшить количество ошибок. связанных с неосвобождением памяти, путем централизованного управления временем жизни
Ссылки по теме:

[1] Apache Portable Runtime Pools
[2] Boost Pool Library
Subscribe

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 9 comments