Claude Code по заданию Торвальдса ускорил чтение файлов в Linux в 23 раза, но пропустил критичный баг, который нашли люди

torvalds-claude-code-linux

Разработчики ядра Linux активно дискутируют, стоит ли доверять разработку ИИ-моделям. Тем временем сам создатель Linux Линус Торвальдс поручил Claude Code написать решение задачи, которую люди не могут решить более двух лет: под его руководством агент написал экспериментальные патчи для страничного кеша (page cache), где в оперативной памяти хранятся данные файлов. Это решение позволит Linux быстрее отдавать данные программам, которые во много потоков читают один и тот же файл, и выигрыш тем больше, чем больше ядер у процессора. И Claude написал патч, который ускорил чтение одного файла до 23 раз на мощном железе. Но всего через четыре часа после публикации Кирилл Шутемов, разработчик ядра Linux, нашёл в патчах баг – состояние гонки (race condition), которое пропустили тесты, написанные Claude Code. История вышла показательной: ИИ помог сдвинуть задачу, на которой люди годами буксовали, но полностью доверять разработку ИИ пока рано.

Коротко

  • Торвальдс поручил Claude Code задачу, которую разработчики ядра не могли решить два с половиной года: модель написала код и тесты, Торвальдс выбрал подход, направлял работу и сам делал замеры.
  • Прирост – около 23× в синтетическом тесте на рабочей станции с многоядерным процессором AMD Ryzen Threadripper при 64 потоках чтения и около 3× на ноутбуке с Core i7-8565U при восьми. С защитами процессора, включёнными по умолчанию, тот же тест в переработанной версии даёт около 4,5× на ext4, а в реальных задачах выигрыш будет ещё меньше.
  • Через четыре часа после публикации Шутемов нашёл в патчах баг – состояние гонки, которое пропустили тесты, написанные Claude Code. Торвальдс передал Шутемову доработку серии.
  • Патчи экспериментальные: первая версия – в ветке noref-filemap-read-with-llm, серия rcu-free-v3 и обсуждение – в рассылке LKML. 19 октября Шутемов выложил переработанную версию; в ядро код пока не вошёл и в Linux 7.4 уже не попадёт.

Чтение файла упиралось в один счётчик

Два с половиной года разработчики Linux не могли решить одну проблему: когда много потоков одновременно читают один файл, ядро начинает тормозить. На неё в 2024 году указал Мэтью Уилкокс (Matthew Wilcox), разработчик ядра Linux из Oracle. По словам Уилкокса, у одного небольшого клиента программа читала файл порциями по 64 байта, и при таких маленьких порциях работу заметно замедлял один служебный счётчик.

Когда данные уже лежат в страничном кеше, ядру не нужно читать их с накопителя. Но перед копированием оно увеличивает счётчик ссылок на folio – блок из одной или нескольких страниц памяти, – а после уменьшает его. Так ядро отмечает, что память ещё используется и освобождать её рано.

Пока файл читает один поток, это почти ничего не стоит. Но если файл читают сразу много потоков, ядрам процессора приходится постоянно передавать друг другу этот счётчик, и они больше ждут, чем читают. Такие передачи видны как события load HITM: одному ядру нужны данные, которые другое только что изменило в своём кеше. Позже Торвальдс измерил масштаб: в его тесте с восемью потоками на строку кеша со счётчиком пришлось 99,92% таких событий.

Просто убрать счётчик нельзя: тогда страницу могут освободить и отдать под другие данные прямо во время копирования. Торвальдс, который с 1991 года руководит разработкой ядра, тогда же выложил в рассылку разработчиков черновое исправление. Черновик работал достаточно хорошо, и, как пишет Торвальдс, он полтора года пользовался им на своём компьютере, пока другие разработчики не показали, насколько исправление сломано. Осенью 2025 года Шутемов пробовал довести этот черновик, Илья Гладышев (Ilya Gladyshev) – совсем другой подход, но у обоих, по словам Торвальдса, остались проблемы.

По данным The New Stack, прежние решения копировали данные без счётчика, а корректность проверяли уже после. Но проверка пропускала часть гонок – например, когда страницу освобождали, а на её место в кеше вставала новая. На этом попытки и останавливались.

Как Торвальдс решал задачу вместе с Claude Code

В итоге к задаче вернулся сам Торвальдс – и на этот раз не один. До этого он считал ИИ полезным инструментом, не больше: в мае признался, что злится, когда слышит, будто ИИ пишет «99% кода», в июле написал, что Linux не анти-ИИ-проект, хотя пользоваться такими инструментами никто не обязан, а в августе нейросеть помогла ему в отладке драйвера. Поводом стал саммит мейнтейнеров ядра 8 октября в Праге: одной из главных тем там было использование LLM в разработке, и Торвальдс решил проверить, удастся ли с помощью модели наконец довести дело до конца.

Он зашёл с другой стороны: вместо того чтобы ловить гонку после копирования, решил убрать её причину. Страницы, из которых так читают, ядро теперь освобождает не сразу, а с задержкой: механизм RCU дожидается, пока закончатся все уже начавшиеся операции чтения. Раз память не могут отдать под другие данные посреди копирования, счётчик в быстром пути чтения больше не нужен.

Реализацию Торвальдс поручил Claude Code: модель подготовила код, тесты, разбор открытых проблем и черновик сопроводительного текста. Торвальдс этого не скрывал: ветку с патчами назвал noref-filemap-read-with-llm («…с LLM»), а в описании коммита написал, что всё это «сделано с ИИ-ассистентом для программирования под моим руководством», и назвал ассистента прямо – Claude Code. Замеры он проводил сам, на своём компьютере.

Первую версию – восемь патчей в ветке noref-filemap-read-with-llm – 11 октября заметил в репозитории Торвальдса Майкл Ларабел (Michael Larabel) из Phoronix. Через два дня Торвальдс вынес на обсуждение в LKML доработанную серию из десяти патчей – ветку rcu-free-v3.

Бенчмарки и ограничения ускорения

Первую версию Торвальдс проверял на ноутбуке с Core i7-8565U, доработанную – на рабочей станции с AMD Ryzen Threadripper 3970X. Это многоядерный процессор для рабочих станций, он выполняет 64 потока одновременно. Чем больше ядер борются за один счётчик, тем дороже обходится каждая операция чтения: до патчей она стоила около 3 000 тактов процессора на ноутбуке и около 20 000 на рабочей станции, а после патчей – около 730 на обеих машинах. Поэтому и выигрыш на рабочей станции оказался намного больше.

Тест До После Результат
Рабочая станция с Threadripper 3970X, 64 потока, rcu-free-v3, btrfs, синтетический тест 13,3 млн операций чтения/с; ≈20 000 тактов на операцию 304 млн операций чтения/с; 735 тактов на операцию Быстрее в ≈23 раза
Ноутбук с Core i7-8565U, 8 потоков, первая версия, ext4, синтетический тест ≈10 млн операций чтения/с; ≈2 950 тактов на операцию До 33 млн операций чтения/с; 725 тактов на операцию Быстрее в ≈3 раза
Ноутбук с Core i7-8565U, первая версия: 1 поток, чтение 16 байт в буфер, страницы которого ещё нет в памяти ≈4 150 тактов на операцию ≈6 550 тактов на операцию Медленнее в ≈1,6 раза

Цифру 23× нужно читать с оговоркой. В тесте на рабочей станции все 64 потока раз за разом читали один и тот же маленький участок страницы – худший для старого кода случай, который в реальной работе почти не встречается. Поэтому Торвальдс сам предупреждает, что такого прироста не увидит ни одна реальная нагрузка.

«Такты на операцию» – сколько тактов процессора ядро тратит на одну операцию чтения. Сравнивать именно их Торвальдс советовал потому, что ноутбук при нагреве сбрасывал частоту и число операций в секунду от запуска к запуску менялось. Ноутбук работал с ext4 и отключёнными защитами от уязвимостей процессора.

У ускорения есть и цена: если страницы буфера, куда копируют данные, ещё нет в памяти, быстрая попытка вызывает лишнее исключение процессора, и ядро возвращается к прежнему механизму. Такая операция обходится дороже, чем без патчей.

Баг, который пропустили тесты Claude Code

Главное испытание ждало патчи не в бенчмарках, а на ревью. Уже через четыре часа после публикации Шутемов, который занимается подсистемой управления памятью Linux, нашёл в серии баг – состояние гонки в функции чтения filemap_read_rcu_batch(). Баг сидел в коде, который Claude Code написал под руководством Торвальдса, и тесты, написанные той же моделью, его пропустили. До публикации его не заметил и сам Торвальдс.

Один поток выбирает страницу для чтения, а другой в этот момент заменяет её в кеше и дописывает файл. Первый поток видит новый размер файла, но читает старую страницу – в том числе участок, куда данные этого файла не записывали. Отложенное освобождение тут не спасает: оно гарантирует, что страницу не отдадут под чужие данные, но не то, что она всё ещё соответствует файлу. По сути, это та же ловушка с заменой страниц, на которой спотыкались прежние решения, только в новой форме.

Тесты этот сценарий не ловили. В замерах потоки раз за разом читали один и тот же неизменный файл, а баг проявляется, только если в тот же момент страницу вытесняют из кеша, а файл дописывают. Чтобы поймать такое совпадение, нужно заранее знать, какую последовательность событий проверять.

В этот раз баг поймали до того, как код попал в ядро, потому что Шутемов знал, куда смотреть: год назад он сам пытался довести черновик Торвальдса и видел, на чём ломались прежние решения. Без рецензента, который так хорошо знает эту подсистему, баг мог бы дойти и до ядра.

А цена такого бага высока. Ядро Linux работает на большинстве серверов и в каждом Android-смартфоне, а через страничный кеш проходит почти любое чтение файла. Если бы патчи вошли в ядро как есть, программа, читающая файл, который в этот момент дописывают, – например журнал или базу данных, – в редких случаях получала бы данные, которых в файле никогда не было, и не узнала бы об этом. Такие сбои почти не воспроизводятся, и найти их в работающих системах очень трудно.

Шутемов сразу приложил исправление: после чтения размера файла ядро ещё раз проверяет, что страница по-прежнему в кеше. Торвальдс ответил меньше чем через час: предложил читать размер раньше и обойтись одной проверкой, а заодно попросил Шутемова взять всю серию на себя – с пятницы у Торвальдса начинался отпуск, а на следующей неделе – окно слияния. Шутемов согласился и на следующий день прислал переработанное исправление, в котором порядок проверок для процессора закрепляют барьеры памяти.

Параллельно рецензенты спорили об устройстве самого механизма – флаге PG_rcu_free, которым помечаются страницы с отложенным освобождением. Уилкокс предлагал заменить его отдельным типом страницы, но Торвальдс возразил: страницу помечают задолго до освобождения, в том числе пока она ещё отображена в память программы, а тип страницы для этого не подходит. Шутемов предложил компромисс – оставить флаг только для 64-битных систем, где свободных флагов больше. Дэвид Хильденбранд (David Hildenbrand) из Arm его поддержал, и в новой версии серии флаг и весь механизм работают только на 64-битных системах.

Когда патчи могут попасть в Linux

Получив серию, Шутемов переработал её за пять дней. 18 октября вышел Linux 7.3 и открылось окно слияния 7.4, а на следующий день Шутемов опубликовал новую версию – 18 патчей, семь из них написал Торвальдс. Тест остался тем же синтетическим, но Шутемов прогнал его с защитами процессора, включёнными по умолчанию: на его машине они добавляют к каждому вызову чтения около 400 нс. С ними при 64 потоках чтение с ext4 ускорилось примерно в 4,5 раза (с 15 до 70 млн операций чтения в секунду), с XFS – менее чем вдвое, а в одном потоке разницы нет. Без защит выигрыш на ext4 вырастает до 13 раз. Серия по-прежнему выставлена на обсуждение (RFC), целевая версия ядра не названа. В Linux 7.4 она уже не попадёт: в окно слияния идёт только код, заранее принятый мейнтейнерами, так что ближайшая возможность – Linux 7.5, который выйдет уже в 2027 году.

Что это значит на практике

Спор о коде от ИИ эта история не закрывает, но хорошо показывает, где сейчас проходит граница. Роли распределились показательно: Торвальдс выбрал подход, поставил задачу модели и сам сделал замеры, Claude Code написал код и тесты, Шутемов нашёл баг и довёл серию, а решать о включении в ядро будут разработчики подсистемы памяти. Это совпадает с позицией Торвальдса: понимать нужно не только свои промпты, но и итоговый код, иначе его не получится долго поддерживать.

Отсюда и мораль для пользователей Claude Code, Codex и других инструментов генерации кода. ИИ смог написать решение, но не увидел всех его слабых мест: баг, который пропустили его же тесты, нашли и исправили люди, глубоко погружённые в код ядра. Значит, полностью доверять ИИ-агенту нельзя, даже когда задачу ему ставит сам Торвальдс. Но и польза от него очевидна: задачу, которая два с половиной года стояла на месте, с его помощью за короткий срок довели до решения, которое теперь дорабатывают люди.

Торвальдс, которого злят разговоры про «99% кода от ИИ», в итоге сам показал, почему эта цифра мало что значит: написать код может и модель, но отвечать за него всё равно человеку.


neurohive telegram
Подписаться
Уведомить о
guest

0 Comments
Старые
Новые Популярные