Многопоточные пул-распределители - PullRequest
3 голосов
/ 07 января 2011

У меня возникли некоторые проблемы с использованием распределителей памяти в пуле для объектов std :: list в многопоточном приложении.

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

Я пытался использоватьобщий потокобезопасный пул одноэлементной памяти и обнаружил, что производительность неудовлетворительная, как и ожидалось.

Это сильно упрощенная версия того, что я пытаюсь сделать.Многое было включено в способ псевдокода, извините, если это сбивает с толку.

/* The thread functor - one instance of MAKE_QUADTREE created for each thread
 */
class make_quadtree
{
private:

/* A non-thread-safe memory pool for int linked list items, let's say that it's 
 * something along the lines of BOOST::OBJECT_POOL
 */
    pooled_allocator<int> item_pool;

/* The problem! - a local class that would be constructed within each std::list as the
 * allocator but really just delegates to ITEM_POOL
 */
    class local_alloc
    {
    public :
    //!! I understand that I can't access ITEM_POOL from within a nested class like
    //!! this, that's really my question - can I get something along these lines to
    //!! work??
        pointer allocate (size_t n) { return ( item_pool.allocate(n) ); }
};

public :
    make_quadtree (): item_pool()    // only construct 1 instance of ITEM_POOL per
                                     // MAKE_QUADTREE object
    {
    /* The kind of data structures - vectors of linked lists
     * The idea is that all of the linked lists should share a local pooled allocator
     */
        std::vector<std::list<int, local_alloc>> lists;

    /* The actual operations - too complicated to show, but in general:
     *
     * - The vector LISTS is grown as a quadtree is built, it's size is the number of
     *   quadtree "boxes"
     *
     * - Each element of LISTS (each linked list) represents the ID's of items
     *   contained within each quadtree box (say they're xy points), as the quadtree
     *   is grown a lot of ID pop/push-ing between lists occurs, hence the memory pool
     *   is important for performance
*/
    }
};

Так что на самом деле моя проблема в том, что я хотел бы иметь один экземпляр пула памяти на экземпляр функтора потока, новнутри каждого потока функтор разделяет пул между несколькими объектами std :: list.

Ответы [ 2 ]

0 голосов
/ 07 января 2011

Распределитель, специфичный для потока, является довольно сложной задачей.

Я потратил некоторое время на поиск распределителя, специфичного для потока, "с полки".Лучшее, что я нашел, это клад (hoard.org).Это обеспечило значительное улучшение производительности, однако у накопителя есть некоторые серьезные недостатки

  • Я испытал некоторые сбои во время тестирования
  • Коммерческое лицензирование стоит дорого
  • Это «перехватывает» системные вызовыв malloc, метод, который я считаю хитрым.

Поэтому я решил развернуть свой собственный распределитель памяти для потоков, основанный на boost :: pool и boost :: threadspecificptr.Это потребовало небольшого количества серьезно продвинутого кода на C ++, но теперь, похоже, работает хорошо.

Прошло уже несколько месяцев с тех пор, как я посмотрел на детали этого, но, возможно, я смогувзгляните еще раз.

Ваш комментарий о том, что вы ищете специфичный для потока, но не безопасный для потока распределитель.Это имеет смысл, потому что, если распределитель является специфичным для потока, он не должен быть потокобезопасным.Тем не менее, по моему опыту, дополнительное бремя обеспечения безопасности потоков является тривиальным, до тех пор, пока не возникает спор.

Тем не менее, вся эта теория забавна, но я думаю, что мы должны перейти к практичности.Я считаю, что нам нужна небольшая инструментированная отдельная программа, которая демонстрирует проблему, которую нужно решить.У меня было что-то похожее на очень похожую проблему с распределением std :: multiset, и я написал программу, которую вы можете увидеть здесь: Параллельное чтение из контейнеров STL

Если вы можете написать что-то подобное, показывая вашипроблема, тогда я могу проверить, может ли мой распределитель памяти конкретного потока быть применен с преимуществом в вашем случае.

0 голосов
/ 07 января 2011

Почему бы просто не создать экземпляр local_alloc со ссылкой на make_quadtree?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...