Boost object pool problem ze złożonością obliczeniową

0

Witam,

W swoim kodzie zaimplementowałem memory poola z biblioteki boost:<boost/pool/object_pool.hpp> aby móc szybko zaalokować pamięć dla dużej ilości obiektów pewnej struktury o niewielkim rozmiarze oraz szybko ją potem zwolnić. Są to proste obiekty i wystarcza im zwolnienie bloku pamięci więc nie trzeba martwić sie o wywoływanie dla nich destruktorów itp.
Rozwiązanie to działa. Problem pojawia się gdy obiektów jest dużo i chcę zwalniać pamięć szybko pojedyńczych obiektów. Okazuje się że metody destroy(wywołuje konstruktor) oraz free (nie wywołuje konstruktora) przy sporym rozmiarze memory poola działają znacznie wolniej niż zwykły operator delete. Wydaje mi się że jest to spowodowane przez funkcję:
void * simple_segregated_storage<SizeType>::find_prev(void * const ptr)
W której jest wyszukiwanie czy dany adres znajduje się we "free list"

W dokumentacji http://www.boost.org/doc/libs/1_61_0/libs/pool/doc/html/boost_pool/pool/interfaces.html znalazłem taką informację:

Ordered versus unordered
An ordered pool maintains it's free list in order of the address of each free block - this is the most efficient way if you're likely to allocate arrays of objects. However, freeing an object can be O(N) in the number of currently free blocks which can be prohibitively expensive in some situations.

An unordered pool does not maintain it's free list in any particular order, as a result allocation and freeing single objects is very fast, but allocating arrays may be slow (and in particular the pool may not be aware that it contains enough free memory for the allocation request, and unnecessarily allocate more memory).

Czy wobec tego rozwiązaniem mojego problemu może być unordered pool i jeśli tak to czy jakaś implementacja memory poola z biblioteki boost opiera się na tej zasadzie działania i czy mogę z niej skorzystać?

Z góry dziękuje za pomoc.

0

Przejrzałem dokumentacje, którą Podałeś - przy żadnym interfejsie nie ma informacji czy utrzymywana jest lista wolnych bloków. Ale widzę, że Użyłeś object_pool; skoro nie wiadomo, to co stoi na przeszkodzie sprawdzić wszystkie interfejsy?

0

Tylko jakie będą skutki uboczne zastosowania takiego rozwiązania? Z tego co wywnioskowałem z opisu pamięć będzie zwalniana dla pojedynczych obiektów więc będą powstawały wolne "luki" w obszarze memory poola. I gdy będę chciał zaalokować tablicę obiektów to prawdopodobnie nie wykorzysta tych nieużywanych obszarów po zwolnionych obiektach tylko weźmie sobie więcej pamięci z systemu żeby zmieścić tablicę. Natomiast gdy zażądam pamięci dla pojedynczego obiektu to wykorzysta również zwolnione obszary. Jeżeli tak to wszystko ok.
Moja obawa związana jest z tym że w takim rozwiązaniu w ogóle nie wykorzystamy zwolnionych obszarów pamięci i powiedzmy naprzemienne operacje "constuct" i "destroy" będą alokowały cały czas nowe obszary pamięci aż do zniszczenia memory poola. Pomimo tego że tak naprawdę zajęty będzie obszar tylko dla jednego obiektu.

0

Czyli Obawiasz się, że memory pool będzie działał szybko, ale powodował coś w rodzaju wycieku pamięci? To chyba trzeba by to potestować i przejechać jakimś profilerem.

0

Pytanie co jest bardziej prawdopodobne:

  • błąd w boost, tworzona przez wymiataczy i używana w milionie projektów?
  • błąd w twoim kodzie, którego nie pokazałeś

Jeśli widzisz problemy wydajności w swoim programie, to nie zgaduj fdzie jest problem, ale użyj prolifera by zlokalizować problematyczne miejsce.
Z doświadczenia własnego i obserwacji pytań w internecie wynika, że ludzie często optymalizują nie to co trzeba, bo kierują się własnym "widzi mi się".

Z twojego opisu wynika, że nie rozumiesz czemu ma służyć object_pool i kiedy należy go używać.

1 użytkowników online, w tym zalogowanych: 0, gości: 1