Comments 31
Не совсем понятно, зачем выделять remapToHugeStep3 в отдельную функцию и делать ассемблерную вставку, когда в стеке и так лежит адрес возврата в remapToHugeStep1?
Вот тут с идеями об использовании huge pages для кода уже игрался: https://easyperf.net/blog/2022/09/01/Utilizing-Huge-Pages-For-Code
Причем в одном из подходов в huge pages грузится, похоже, код прямо из (специально подготовленного) файла штатно без каких-либо телодвижений. Т.е. " Linux позволит использовать большие страницы только для анонимных отображений в память - то есть, для тех, которые не связаны ни с каким файлом " не вполне верно. На что также намекает строчкаFileHugePages
в /proc/meminfo
В man про madvise действительно сказано, что он может сделать большими только страницы анонимных отображений.
В докладе упоминается возможность использовать большие страницы другим способом, не с помощью madvise, но он не подходил из-за того, как запускали тесты производительности.
Глянул одним глазком на доклад (надо будет посмотреть целиком :)) - действительно, товарищи эту статью видели и им действительно это не подходит; им нужно кровь из носу использовать Transparent Huge Pages, потому они и занимаются нехорошими вещами.
"Нормальному" же пользователю, которому надо сервис почему-либо загнать в HP, будет в 95% случаях проще настроить линукс, как описано в той статье )
Случайно наткнулся на патч от Google, где они решали ту же проблему для Chrome; там фиксили mremap с thp. Т.е. может быть в новых версиях Linux можно вместо всей этой чешуйни просто после копирования данных сделать mremap их по оригинальному адресу; но надо смотреть на выравнивание адресов данных.
Еще одна альтернатива была бы вынести весь функционал по переезду данных с page cache на anonymous в отдельный DSO, и тогда не надо было бы городить весь этот изврат с написанием кода, работающего в любом месте в памяти.
Я что-то ничего не понял. Вы не могли бы прислать ссылку на этот патч?
https://github.com/torvalds/linux/commit/550a7d60bd5e35a56942dba6d8a26752beb26c9f
И использование - https://chromium.googlesource.com/chromium/src/+/refs/heads/main/chromeos/hugepage_text/hugepage_text.cc - выделяют блок hugepage памяти (выровненный по границе большой страницы), копируют данные, задают правильные права, а потом вместо всех телодвижений по переезду - просто делают mremap этого блока по исходному адресу (тоже выровненному по границе большой страницы - это важно). Имеющиеся маппинги автоматически закрываются, hugepages переезжают на новый виртуальный адрес и все.
Архитектура Кликхауса такова что они собирают всё в единый статический бинарник со всеми зависимостями. А т.к. это СУБД то там слишком дорого ходить по юникс сокету в другой демон по любому вопросу.
Ну КХ огромный проект с кучей зависимостей - такой размер бинарника оправдан.
Существенное увеличение бинарника из-за 256-битных типов действительно странно, надо глядеть почему так получилось.
Вы разработчик clickhouse?
В том числе, контрибутил туда, плюс давно с ним работаю.
То что это СУБД не означает, что там нечего выносить за пределы единого бинаря.
Означает.
В СУБД любая часть кода должна быть доступна сразу т.к. запрос должен быть обработан максимально быстро.
Если это потребует ещё и сериализации данных чтобы запихать их в Pipe и разобрать с той стороны другим демоном, дождаться ответа потом - производительность упадёт ниже плинтуса.
У них даже хеш-функций различных реализовано штук 60 в коде чтобы использовать оптимальную в каждом случае - производительность складывается из мелочей.
Большой солидный проект никто так применять не будет.
Ну, вам конечно виднее, чем разработчикам самой быстрой колоночной СУБД на рынке... Я думаю что они этот вопрос продумывали и остановились на таком подходе по сумме причин.
Для большого проекта это даже хуже, потому что чтобы залатать дыру в безопасности нельзя будет просто сделать инкрементальный апдейт заменя одну версию openssl на другую и пропатчив это "на лету".
Это давний холивар тех кто "за" статику и "против", каждый выбирает свою комбинацию плюсов и минусов.
А как насчёт солидного проекта под названием ВК. Бекенд - это vk.bin на 4гб на с++. Где то была статья тут на эту тему. И ничего, все работает. А тут каких то жалких 400м;)
Ну, ВК это супер огромный проект. Понятно, что будет также больше число багов. Все таки там и подсистем очень много. Пишут разные команды, разные квалификации.
Так как ВК это большой проект, то там скорее всего оправданы специализированные базы данных, а не общего назначения. Если написать свою бд, то можно очень гибко управлять хранением данных (а значит и экономить сильно место на дисках), также быстрее обрабатывать запросы, чем в бд общего назначения.
Все таки вы по одному видео заявляете, что ВК в плане кода дерьмо. Согласитесь это странно. Чтобы так сказать, вам надо оценить все проекты, весь код.
А что такое хорошая структура большого выконагруженного проекта по вашему?
Чтобы говорить хорошая надо сначала определить критерий хорошести - удобство чтения и сопровождения кода, скорость работы кода, милимальное кол-во кода идр? Какой критерий? Не забывем, что на их объемах память стоит дорого и надо экономить
Ps: отдельно хочу заметить , что не всем проектам надо копировать структуру и подходы от крупных проектов. А 95% случаев достаточно распространенных проверенных стеков, реляционной СУБД итд. И не надо лезть в какие то дебри. Вот когда проект сильно начитает нагружаться пользователями, тогда уже надо думать. Но до этого в 90% случаях просто не дойдет;)
Да по тому же Telegram видно, что там олимпиадные, простите за ругательство, подходы.
Существенное увеличение бинарника из-за 256-битных типов действительно странно, надо глядеть почему так получилось
Есть подозрение что там все внутри на генериках и добавление типов вызвало "комбинаторный взрыв" тк понадобилось синтезировать код для всех новых зависимых типов (конверторы, сериализаторы, проверки итд).
А точно есть смысл разбиения на отдельные бинарники? С точки зрения "page cache" Linux ядра совершенно не важно отдельные бинарники или это единый, загружены будут только используемые страницы, и в памяти будут находиться именно используемые страницы.
Выигрыш будет только за счет того, что таблицы страниц будут в случае нескольких исполняемых файлов меньше, но зато будет использоваться на дополнительные ресурсы межпроцессорное взаимодействие - допольнительные код взаимодействия, буферы, логика ожидания старта каждой из частей и т.д. и т.п. Без измерений совершенно неочевидно, что этот вариант однозначно выигрышный. Идея с уменьшение размера таблиц страниц за счет увеличения размера страниц кажется более простой и точно приносящей выгоду.
Тут какой-то огромный монолит на полгига бинарника. При любом подходе будут и cache misses и page reloads
не будет, ядро не умеет выгружать huge pages, всё это дерьмо богатство зависнет в памяти бесполезным грузом.
А будет ли теперь работать CH, если huge pages нет? Например в ряде вариантов контейнерной виртуализации?
Да. Huge pages включаются только для тестов производительности, в production их нет
Ps извините если ответ будет не грамотным, отвечаю исходя из своего опыта работы с кликхаус
В контейнеры пихать клик категорически не рекомендуется так понимаю, ибо контейнеры не стабильные и падения скорее норма, а клик считает всегда, у вас будет искажения результатов. Да возможно есть задачи и способы, но это точно не основная масса применения продукта.
Из статьи понял всё кроме одного: что, блин, такое Clickhouse и для чего оно надо?!))
И зачем ему работа с TLB?!
ClickHouse — это колоночная аналитическая СУБД с открытым кодом, использующая диалект SQL. Её особенность в том, что она колоночная, и за счёт этого многие запросы работают быстрее, чем в mysql или postgres
C TLB работает любая программа на компьютере - он используется для кеширования маппинга страниц виртальной памяти в страницы физической памяти. Без него все программы работали бы очень медленно
Найти и уничтожить: как Clickhouse удаляет собственный код из памяти и переключается на использование Huge Pages