Обязательно посмотрите jemalloc, он очень хорош, особенно насчет фрагментации памяти.
И я думаю, что лучшим выходом будет не подобным образом с помощью макросов подменять malloc и прочие функции для работы с аллокаторами, а написать обертку что-то типа ng_alloc, которая по-дефолту будет вызывать malloc и прочие стандартные функции аллокатора соответственно. И ключ компиляции, что-то типа OBSD_ALLOCATOR_ENABLED, и если он выставлен ng_alloc будет вызывать ngx_obsd_malloc. И я думаю такой пач имеет больше шансов быть принятым, так как для многих он может быть выходом.
Вопрос для чего. На linux в libc используется ptmalloc — там суть в том, что поверх lea используется per thread heap/arena — что сильно снижает contention в условиях SMP. На сегодня это один из самых быстрых аллокаторов, которые доступны стандартно.
nginx же сам по себе под SMP практически не заточен — там дофига локинга и оптимизация под cache line также не везде есть. В nginx все события принимаются и предобрабатываются ОДНИМ (!) потоком, потом они складываются в одну очередь, которую обрабатывают обработчики — что приводит к борьбе между ними при высокой нагрузке.
Есть и другой подход, когда каждый обработчик обрабатывает только свои соединения. Таким образом решается проблема с локингом и конкуренцией — события тупо обрабатываются без локинга, т.к. они никогда не попадут в очередь соседних обработчиков.
Я хотел простой mmap-based (а не brk/sbrk) аллокатор который будет заточен под стратегию использования в памяти nginx. Причем nginx для linux, что мне интересно.
Я не совсем понимаю что вы хотели сказать этим комментарием.
Суть не в методе выделения памяти, а в том, как выледенная память режется на блоки и распределяется. Сегодня практически любой нормальный сервер SMP и использовать аллокаторы и пулы не заточенные под SMP — это жесть.
Под незаточен я имел ввиду — не сильно оптимизирован, но вообще-то умеет. По крайней мере выравнивание размера структур до cache line size кое-где присутствует.
В nginx более правильно задать другой вопрос — зачем там вообще что-то делать с malloc, если там для основных рантайм вещей используется свой код (а не системный generic use allocator)?
Если вы это все на linux делали, то результат потребления памяти вполне может быть понятен. По крайней мере нужно знать — что лежит за тем, что использовалось. В linux libc — ptmalloc на базе lea — он весьма неплох и для generic use, и для SMP, и для быстродействия.
Да за счет per cpu/thread/process куч он менее экономно относится к памяти, но за быстродействие нужно платить :)
Что касается различных slab и подобных аллокаторов, которые используют память компактно — они (по крайней мере в моих тестах) все медленнее.
1) пред-обработанные события складываются в очередь, которая разгребается многими воркерами
2) воркеры выполняются на разных cpu (если их много)
3) обработка последовательных событий для одного и того же соединения может таким образом выполняться не только в контекстах разных CPU но и разных процессов
В реальной жизни обычный malloc, который выделяет память только в рамках текущего процесса — к обработке соединений в nginx не имеет особого отношения.
Если есть реальное желание что-то ускорить — займитесь тем, что реально используется.
А так, если думаете, что я тут сказки рассказывают — посмотрите в коде nginx, где реально используется обычный malloc :) Судя по тому, что вы написали в статье — результаты вас удивят.
Забыл про пункт 3) написать, что работа идет таким образом с shared памятью. В связи с чем любая оптимизация системного маллока для nginx теряет смысл, в принципе.
Изначально я думал, что речь идет как раз о шаред памяти, но почитав и вникнув понял, что речь идет совсем о другом.
Как я уже написал — «аллокатор который будет заточен под стратегию использования в памяти nginx» — эта фраза с моей точки зрения бессмыссленна в отношении malloc, который в nginx используется в основном на фазе инициализации сервера для не-shared памяти.
Советую все же почитать материалы по аллокаторам и изучить современные подходы к задачам. А то глядя на выбор аллокатора на глаз на основе «на глаз лучше рвет всех obsd-like» заставляет сомневаться, что вы понимаете разницу между свойствами различных типов аллокаторов и задачами для которых они предназначены.
С чего вы взяли, например, что ptmalloc из linux хуже BSD-шного, где используется принцип локинга, который не дружит с SMP в плане маштабируемости?
А ведь масштабируемость для подобных серверов главное — не так ли?
А на основе чего вы выбрали аллокатор для замены? Исследовали какие-либо материалы на тему? :) Почему именно это аллокатор, а не другой? Где сравнения с более современными аллокаторами?
P.S. Когда быстродействие отличается незначительно, то можно сделать выбор в сторону более компактного аллокатора, а не более быстрого — зачастую это понятия несовместимые :)
P.P.S. Еще более интересно каким образом измерялось «потребление памяти около 40 мегабайт на каждый worker процесс» в условиях copy-on-write и разделяемой памяти между процессами? :)))))
У пациента есть еще мистическая подсистема кеша и работа с объектами в папке /tmp
В приципе я изначально подумал что доработана как раз система аллокатора логических ресурсов( кэш и временые обьекты, и чего тама еще бывает), а не физических(память)
Аллокатором (от английского to allocate – «размещать», «выделять») называется совокупность механизмов, ответственная за распределение памяти и реализующая операции выделения, освобождения и (опционально) изменения размеров ранее выделенных блоков.
Угу, но если посмотришь на код оригинальный этого там не было. Я это писал, ибо расчитывал использовать в другом виде. Потом только в голову пришло вкорячить в потроха nginx (да-да, изначально это грузилось через ld_preload).
А не сделал я его в таком формате, по простой прчини, мне так удобнее запускать nginx ;)
Да, и задачи ускорять php, perl и прочее не было. Еще учитывать надо что это будет хорошо на той стратегии по использованию памяти, какую выбирает nginx.
Вы вводите в заблуждение людей.
В nginx есть свой pool-based аллокатор. А тот что вы добавили — так это замена системному (libc), а никак «другой аллокатор nginx».
Вы предлагаете хачить системный аллокатор? Или делать его через preload? Первое опасно, второе не удобно для отладки (я не уверен что он всегда будет запускаться с этм кодом, а так, этот код, в него жестово вставлен).
Далее, я покатаюсь, с недельку, на этих аллокаторах, пойму какой из них мне понравился больше, и начну их сильно хачить. И в итоге получу *очень* сильно специфичный аллокатор для nginx, который использую.
nginx: другой аллокатор