Многопоточные блокировки памяти для C/С++

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

До сих пор я разорван между:

  • Sun umem
  • Google tcmalloc
  • Распределитель блоков Intel Threading Building Block
  • Накопитель Эмери Бергер

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

Ответ 1

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

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

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

Ответ 2

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

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

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

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

И в зависимости от вашего варианта использования универсальный многопоточный распределитель может не быть тем, что вы хотите использовать вообще; если вы постоянно являетесь объектами malloc и free'ing, которые имеют одинаковый размер, вы можете просто написать простой распределитель slab. Распределение slab используется в нескольких местах ядра Linux, которые соответствуют этому описанию. (Я бы дал вам пару полезных ссылок, но я "новый пользователь", и Qaru решил, что новым пользователям не разрешается быть слишком полезными в одном ответе. Однако Google может помочь в этом достаточно хорошо.)

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

enter image description here

Ответ 7

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

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

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

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

Ответ 8

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