Многопоточные распределители памяти для C / C ++

В настоящее время у меня есть сильно многопоточное серверное приложение, и я ищу хороший многопоточный распределитель памяти.

Пока что разрываюсь между:

  • Умэм солнца
  • Tcmalloc от Google
  • Распределитель строительных блоков потоковой передачи от Intel
  • Клад Эмери Бергера

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


person Robert Gould    schedule 29.09.2008    source источник
comment
Какие конкретные проблемы вы пытаетесь решить с помощью текущего диспетчера кучи по умолчанию, который вы используете? И что это?   -  person Tall Jeff    schedule 29.09.2008
comment
В своем приложении попробуйте проверить, можно ли повысить производительность за счет использования локального хранилища потока. Если есть возможность сделать это, выигрыш может быть лучше, чем при использовании многопоточного распределителя.   -  person trshiv    schedule 29.09.2008


Ответы (8)


Я использовал tcmalloc и читал о Hoard. Оба имеют схожие реализации, и оба достигают примерно линейного масштабирования производительности по отношению к количеству потоков / процессоров (согласно графикам на соответствующих сайтах).

Итак: если производительность действительно настолько важна, проведите тестирование производительности / нагрузки. В противном случае просто бросьте кубик и выберите один из перечисленных (с учетом простоты использования на вашей целевой платформе).

И из ссылки trshiv, похоже, что Hoard, tcmalloc и ptmalloc являются все примерно сопоставимо по скорости. В целом tt выглядит так, как будто ptmalloc оптимизирован для того, чтобы занимать как можно меньше места, Hoard оптимизирован для компромисса между скоростью и использованием памяти, а tcmalloc оптимизирован для чистой скорости.

person hazzen    schedule 29.09.2008
comment
Ссылка trshiv сейчас здесь - person Paul Coccoli; 29.11.2012
comment
Обе ссылки сейчас не работают - person Assimilater; 27.07.2016

Единственный способ действительно определить, какой распределитель памяти подходит для вашего приложения, - это попробовать несколько. Все упомянутые распределители были написаны умными людьми и превзойдут другие в том или ином микробенчмарке. Если все, что ваше приложение делает в течение всего дня, это malloc один 8-байтовый фрагмент в потоке A и освобождает его в потоке B, и ему вообще не нужно обрабатывать что-либо еще, вы, вероятно, могли бы написать распределитель памяти, который отбивает штаны от любого из перечисленные до сих пор. Это просто не будет очень полезно для чего-то другого. :)

У меня есть некоторый опыт использования Hoard там, где я работаю (достаточно, чтобы одна из наиболее неясных ошибок, исправленных в недавнем выпуске 3.8, была обнаружена в результате этого опыта). Это очень хороший распределитель, но насколько он хорош для вас, зависит от вашей рабочей нагрузки. И вам действительно нужно заплатить за Hoard (хотя это не слишком дорого), чтобы использовать его в коммерческом проекте без использования вашего кода под лицензией GPL.

Очень немного адаптированный ptmalloc2 уже довольно давно является распределителем памяти malloc в glibc, поэтому он невероятно широко используется и тестируется. Если стабильность важна превыше всего, это может быть хорошим выбором, но вы не упомянули об этом в своем списке, поэтому я предполагаю, что это не так. Для определенных рабочих нагрузок это ужасно, но то же самое верно и для любого malloc общего назначения.

Если вы готовы за это заплатить (а цена разумная, по моему опыту), SmartHeap SMP также является хорошим выбором. Большинство других упомянутых распределителей разработаны как вставные замены malloc / free new / delete, которые могут быть выполнены с помощью LD_PRELOAD. SmartHeap можно использовать и таким образом, но он также включает в себя весь API, связанный с распределением, который позволяет вам точно настраивать ваши распределители в соответствии с вашими пожеланиями. В проведенных нами тестах (опять же, очень специфичных для конкретного приложения) SmartHeap был примерно таким же, как и Hoard, когда выступал в качестве замены вставляемого malloc; реальная разница между ними - степень настройки. Чем менее универсальным будет ваш распределитель, тем выше будет производительность.

И в зависимости от вашего варианта использования многопоточный распределитель общего назначения может быть совсем не тем, что вы хотите использовать; если вы постоянно выделяете и освобождаете объекты одинакового размера, вы можете просто написать простой распределитель slab. Распределение Slab используется в нескольких местах ядра Linux, которые соответствуют этому описанию. (Я бы дал вам еще пару полезных ссылок, но я «новый пользователь», и Stack Overflow решил, что новым пользователям не разрешается быть тоже полезными в одном ответе. Google может помочь впрочем, достаточно хорошо.)

person strangelydim    schedule 14.11.2009

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

Вы можете найти это сравнение полезным.

person trshiv    schedule 29.09.2008
comment
Связанная статья перемещена сюда. - person Paul Coccoli; 29.11.2012

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

person Mark Kegel    schedule 29.09.2008
comment
Если это многопоточная среда, выделение стека подходит только для очень маленьких объектов в небольших количествах - вы не хотите попадать в размер стека в потоке, потому что тогда вы получите ту же проблему, что и обычное повреждение памяти. - person hazzen; 29.09.2008
comment
Ага, я согласен с hazzen. Распределение стека, включая локальное хранилище потока, может привести к повреждению памяти, если вы имеете дело с большими или огромными размерами данных. - person trshiv; 29.09.2008

Мы использовали Hoard в проекте, над которым я работал несколько лет назад. Казалось, это отлично сработало. У меня нет опыта работы с другими распределителями. Должно быть довольно легко попробовать разные и провести нагрузочное тестирование, не так ли?

person jfm3    schedule 29.09.2008

Распределитель locklessinc очень хорош, и разработчик всегда готов ответить, если у вас возникнут вопросы. Есть статья, которую он написал о некоторых используемых приемах оптимизации, это интересное чтение: http://locklessinc.com/articles/allocator_tricks/. Я использовал его в прошлом с отличными результатами.

введите описание изображения здесь

person Eloff    schedule 17.08.2013

Возможно запоздалый ответ на ваш вопрос, но

зачем делать маллоки, если у вас резко упала производительность?

Лучшим способом было бы сделать malloc большого окна памяти при инициализации, а затем придумать light weight Memory manager, который будет lease out the memory chunks at run time.

Это позволяет избежать любых системных вызовов при расширении кучи.

person Jay D    schedule 25.04.2012

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

person tav    schedule 17.08.2013