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

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

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

  • Солнце
  • Google tcmalloc
  • Распределитель блоков streamовых блоков Intel
  • Эмир Бергер

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Давайте будем гением компьютера.