group-telegram.com/experimentalchill/242
Last Update:
Очень интересная вещь происходит в memory management Linux в последнее время.
Когда вы аллоцируете память, вы создаёте страницы, обычно они по историческим причинам 4KB, и если вы большая компания, или даже запускаете базу данных, то со временем страниц становится много, появляются проблемы походов в TLB, сервер со временем начинает тормозить. В Google в статье про TCMalloc [1] мы репортили, что 20% всех циклов в датацентре мы проводим в TLB, что не очень то и радует. На помощь приходят Huge Pages, так как их размер побольше, то не происходит больших таблиц и количество TLB простаиваний происходит меньше.
Это показывает, что Huge Pages становятся уже не только хорошей оптимизацией, а в целом Must Have для приложений, которых заботит перформанс.
Проблемы начинают приходить с других сторон в этом направлении. 2MB Huge Pages достаточно сложно выделить ядру из-за большой фрагментации. Если вы на часок оставите шард поискового движка отвечать на запросы, его перф, с одной стороны, улучшается из-за прогретости индекса, с другой стороны ухудшается memory management, так как страницы начинают быть фрагментированы из-за того, что на сервере много всякого происходит. Я пока читал то, о чём сейчас пишу, узнал для себя, что ядро очень сильно разделает все страницы на movable/unmovable. Первые -- те, которые получает пользователь, их ядру легче перемещать, тем самым оно может лучше выделять память на физическом уровне. Unmovable страницы -- те, которые ядро выделяет само, для Network/IO стека, их перемещать сложно, так как ядро к ним доступ имеет мультипоточный и напрямую. Можно лочить всё, чтобы их поменять, но оверхед от такого будет ещё выше, представьте, что вы хотите получить RPC, а тут lock в ядре, оно обновляет все TLB всех ядер, RPC не проходит, беда, печаль.
Простая проблема, которая возникает -- что если 2MB страницы unmovable на физическом уровне находятся рядом с movable? Отсюда начинает сложно дефрагментировать даже movable страницы, если есть задача поближе поставить страницы на физическом уровне. Исторически в ядре утилизации памяти уделяли больше времени, чем вынесение разных видов страниц в разные регионы. Инженеры из Meta на ISCA'23 [2] выложили, наверное, одну из самых интересных статей для меня за последнее время, где они стараются выделять память для movable/unmovable регионов далеко друг от друга на уровне ядра, чтобы улучшать layout памяти на физическом уровне.
Фактически идея достаточно простая -- взять два далеких региона, сказать, что один для movable, другой для unmovable и перемещать границы. Если границы начинают пересекаться, в худшем случае ничего не сделать. Тем не менее, можно делать интересные вещи:
[unmovable region][free space][movable region]
Если есть долгоживущая неперемещаемая страница, то надо её ставить в самое лево, да и вообще, если есть хоть какие-то страницы, лучше их ставить в далёкие от границы места -- тем самым resizing имеет больше шансов быть успешным.
Следующая идея -- считать простую статистику как memory pressure. Она включает в себя время, проведенное в page faults и тому подобное в обоих регионах.
Самая сложная часть -- миграции страниц. Как уже сказано, в софте такую миграцию будет накладно сделать, поэтому инженеры из Meta построили дополнение к LLC на уровне железа. Краткая идея, что для всего процесса надо очень аккуратно оповестить TLB для инвалидации, которая разрешает копирование страницы (в это время все доступы блокируются), а потом уже TLB можно оповестить, чтобы можно было ходить в новую страницу.
Удивительное в этом всём, что приложения получают очень хороший прирост. От 2% до 14%. И код доступен [3], чтобы можно было играться. Моё понимание, что они ещё не выложили это в прод, а пока экспериментируют, но в целом выглядит, как эта тема одна из самых интересных в memory management, память не растет, мы начинаем выкручиваться как можем и делаем все более сложные схемы.
[1] Google TCMalloc Paper
[2] Contiguitas: The Pursuit of Physical Memory Contiguity in
Datacenters
[3] https://lwn.net/ml/linux-kernel/[email protected]/
BY Experimental chill
Warning: Undefined variable $i in /var/www/group-telegram/post.php on line 260
Share with your friend now:
group-telegram.com/experimentalchill/242