A friendly tour of process memory on Linux
Linux создаёт иллюзию непрерывного адресного пространства для процессов, собирая его постранично. Физическая RAM состоит из кадров, распределённых по всей системе, тогда как виртуальное представление — это упорядоченная линия, которую видит программа. Страницы таблицы переводят виртуальные адреса в физические кадры. При первом обращении к странице происходит page fault, и система либо заполняет кадр, либо выдаёт ошибку. При нехватке RAM неиспользуемые страницы перемещаются на диск, а при повторном доступе возвращаются обратно.
Каждый процесс владеет объектом, представляющим всё адресное пространство, разделённым на виртуальные области памяти (VMA) — непрерывные диапазоны с одинаковыми правами доступа и источником данных. Все потоки процесса разделяют это пространство. Управление происходит через mmap (резервирование области), mprotect (изменение прав) и munmap (удаление). Память выделяется лениво — при первом обращении. В /proc/self/maps можно увидеть сегменты бинарного файла, кучу, общие библиотеки и стеки потоков, а также специальные области [vdso] и [vvar] для ускорения системных вызовов. mmap создаёт обещание выделения памяти, но не выделяет страницы сразу.
Комментарии (25)
- Обсуждение критикует использование фраз вроде "without the fog" как признак LLM-написанного текста и вызывает раздражение.
- Участники обсуждают блокировку сайта как угрозу и обсуждают архитектуру 6502 и виртуальную память.
- Поднимается вопрос о том, как технологии развиваются и почему мы не можем вернуться к более простым временам.
How memory maps (mmap) deliver faster file access in Go
Memory maps (mmap) в Go позволяют отображать файлы непосредственно в адресное пространство процесса, избегая копирования данных через буферы. Этот подход устраняет необходимость в системных вызовах read/write, позволяя процессору обращаться к файловой памяти так же, как к обычной памяти. Техника особенно эффективна для больших файлов, когда требуется частый доступ к разным участкам данных, так как mmap обеспечивает постоянное время доступа к любой части файла.
Тесты показали впечатляющие результаты: mmap обеспечивает до 25-кратное ускорение по сравнению с традиционным чтением файлов. В одном эксперименте обработка 1.2GB JSON-файла через заняла 0.4 секунды с mmap против 10 секунд с использованием стандартного пак ioutil. Однако mmap имеет ограничения: он не подходит для очень больших файлов, которые могут не поместиться в виртуальном адресном пространстве, и требует осторожного управления при работе с несколькими процессами. Для оптимальной производительности mmap лучше всего работает с файлами, которые считываются целиком или accessed случайным образом, а не последовательно.
Комментарии (118)
- Обсуждение показало, что mmap не всегда быстрее обычного чтения, особенно при последовательном чтении, и что его преимущество в основном в нишевых сценариях, таких как случайный доступ к большим файлам.
- Участники отметили, что mmap требует осторожности при работе с файлами, которые могут быть изменены или усечены, поскольку это может вызвать ошибки доступа.
- Также было отмечено, что в некоторых ситуациях, таких как чтение из файла в последовательном режиме, обычное чтение может быть предпочтительнее, особенно если файл больше размера оперативной памяти.
- Обсуждение также затронуло влияние различных файловых систем и их взаимодействия с mmap, включая то, что некоторые файловые системы могут не поддерживать mmap или могут вести себя неожиданно при его использовании.
- В конце обсуждение подвело к выводу, что выбор между использованием mmap и обычного чтения должен быть сделан на основе конкретного сценария и требований к производительности, а не на основе предвзятого убеждения в превосходстве одного над другим.
The phaseout of the mmap() file operation in Linux
В ядре Linux начался процесс отказа от устаревшего метода mmap() в структуре file_operations, который используется с 1992 года. Проблема в том, что он даёт драйверам прямой доступ к критическим структурам управления памятью (VMA), что усложняет обработку ошибок и создаёт риски стабильности. Вместо него введён новый метод mmap_prepare(), вызываемый раньше в процессе маппинга и использующий более безопасный дескриптор vm_area_desc.
Этот подход ограничивает влияние драйверов на внутренние структуры памяти, упрощает откат при ошибках и снижает вероятность багов. Переход будет постепенным: драйверы не могут одновременно использовать старый и новый методы, а сотни существующих реализаций mmap() потребуют адаптации. Это шаг к большей инкапсуляции и надёжности подсистемы управления памятью.
Комментарии (19)
- Обсуждение касается внутренней переработки в ядре Linux, а не удаления системного вызова mmap(), что успокаивает участников.
- Упоминается исторический контекст использования /dev/zero для выделения анонимных страниц памяти и его возможная замена.
- Участники шутливо предлагают создать новые виртуальные устройства, такие как /dev/seven (источник символа ^G) и /dev/yes (бесконечный поток "y\n").
- Подчёркивается консервативность и глубокая интеграция структуры file_operations в API ядра, что делает её изменение значительным событием.
- Обсуждается принцип "We do NOT break userspace" (Мы НЕ ломаем пользовательское пространство) как фундаментальный для разработки ядра Linux.
io_uring is faster than mmap 🔥 Горячее
TL;DR
Чтение напрямую с диска быстрее, чем из кеша в памяти: пропускная способность SSD растёт, а латентность памяти стоит на месте. Нужны новые инструменты.
Эксперимент
- Задача: подсчитать количество десяток в 50 ГБ псевдослучайных
int. - Железо: AMD EPYC 7551P, 96 ГБ DDR4-2133, два Samsung PM983a PCIe 3.0 SSD (3,1 ГБ/с каждый) в RAID-0.
- Ограничения:
- Память: 13 ГБ/с на поток (3 канала × 2133 МТ/с × 8 Б / 4 NUMA-домена).
- Диски: 6,2 ГБ/с суммарно.
Код
int* data = mmap(..., size, PROT_READ, MAP_SHARED, fd, 0);
for (...) if (data[i] == 10) count++;
Результаты
- Первый запуск (с диска): 0,61 ГБ/с — ограничение диск.
- Второй запуск (из кеша): 3,71 ГБ/с — всё ещё ниже пропускной способности памяти.
- Бутылочное горлышко: не векторизованный цикл, ~3–4,5 млрд инструкций/с.
Комментарии (120)
- mmap тормозит из-за последовательных page-fault и 4 Кб страниц; io_uring на 6 потоках читает буферы заранее и просто отдаёт готовые.
- Пропущены MAP_POPULATE / MADV_SEQUENTIAL / hugepages — без них сравнение «mmap vs io_uring» нечестое.
- Автор признаёт кликбейтное название «Memory is slow, Disk is fast»; суть: «RAID-0 NVMe даёт больше пропускной канала, чем DDR5-каналов на тестовой машине».
- Под капотом io_uring + O_DIRECT сам управляет кэшем, mmap же полагается на page-cache ядра.
- PCIe-5 ×128 линий серверных CPU уже >1 ТБ/с, что выше DDR5-6400 12-канального узла (~600 ГБ/с), но данные всё равно идут в RAM перед CPU.