io_uring без readahead: почему приложение само должно подсказывать ядру

Io_uring Without Readahead

Разработчик Turso измерил влияние readahead на производительность io_uring. Оказалось, что без него io_uring отправляет только один запрос за раз, что убивает concurrency и не позволяет ядру объединять запросы. С readahead на 32 страницы число запросов к устройству падает с ~196 000 до ~16 300, а 91-93% запросов сливаются. Также автор разбирает затраты на polling-поток и объясняет, почему O_DIRECT приводит к большему числу cache misses по сравнению с buffered I/O.

Один SQE означает отсутствие параллелизма, а без параллелизма блочному слою нечего объединять.
  1. ComputerGuru

    Интересная статья, но она вызвала у меня лёгкую паническую атаку. Бенчмаркинг (с TPC или иначе) — это НЕ способ определить правильный подход здесь; это строго применимо только к базам данных (обычно реляционным), которые фактически «владеют» всем оборудованием, на котором работают. Встраиваемая база данных может использоваться таким образом, если она работает как бэкенд для чистого CRUD-приложения, которое выполняет ~ноль серверного рендеринга, парсинга, валидации и т. д. и по сути является просто асинхронным интерфейсом http-to-SQLite. Но скорее всего, встраиваемая БД будет использоваться и разворачиваться на машинах (не обязательно даже серверах), служащих множеству целей, и должна работать наилучшим образом как в рамках ресурсов, доступных машине, так и в относительном выражении, неизбежно идя на компромиссы, которые могут жертвовать производительностью ради «ценности» с точки зрения использования CPU или памяти.

    Это касается не только бенчмаркинга — это важное соображение *в любое время*, когда вы забираете кэш у ядра, которое является единственным элементом в стеке, имеющим представление о глобальном состоянии и которому можно доверять возврат памяти под давлением, чтобы всё работало вместе. Это не ограничивается только базами данных или даже только памятью: например, FreeBSD имела более чем достаточно проблем, связанных с тем, что ZFS имеет отдельный кэш от ядра (несмотря на более тесную интеграцию между ними и наличие различных механизмов для решения патологических случаев).

  2. marginalia_nu

    Если вы делаете последовательное упреждающее чтение в пользовательском пространстве, почему бы просто не использовать preadv? Это ограничит вас чтением вперёд до следующей резидентной страницы, но, по крайней мере, в моих экспериментах с индексом Marginalia, preadv превосходит io_uring во всех случаях, когда можно использовать один вызов preadv для полного чтения.

  3. amluto

    Мне любопытно, почему выбор стоит между системными вызовами и, конкретно, io_uring с O_DIRECT. Насколько я знаю, Turso похож на SQLite и поддерживает несколько процессов, обращающихся к одной и той же базе данных, и я бы ожидал, что буферизация будет огромным преимуществом в некоторых рабочих нагрузках. Что не так с io_uring без direct? Есть также промежуточный вариант RWF_DONTCACHE.

  4. ErroneousBosh

    Это прокручивалось в моей ленте, и каждый раз я читал это как «Io_uring без Radiohead», и я имею в виду, что можно было бы, но какой в этом смысл?

  5. weatherlite

    Использует ли Io_urine жёлтые потоки?

Ещё за этот день

2026-09-01