Инго Молнар (Ingo Molnar), известный разработчик Linux ядра и автор планировщика задач CFS (Completely Fair Scheduler), предложил для обсуждения в списке рассылки разработчиков ядра Linux серию патчей, затрагивающих более половины всех файлов в исходных текстах ядра и обеспечивающих увеличение скорости полной пересборки ядра на 50-80% в зависимости от настроек. Реализованная оптимизация примечательна тем, что она сопряжена с добавлением самого крупного в истории разработки ядра набора изменений – для включения разом предложено 2297 патчей, меняющих более 25 тысяч файлов (10 тысяч заголовочных файлов в каталогах “include/” и “arch/*/include/” и 15 тысяч файлов с исходными текстами).
Прирост производительности достигается за счёт изменения метода обработки заголовочных файлов. Отмечается, что за тридцать лет разработки ядра состояние заголовочных файлов приняло удручающий вид из-за наличия большого числа перекрёстных зависимостей между файлами.
Работа над реструктуризацией заголовочных файлов заняла более года и потребовала проведения значительной переработки иерархии и зависимостей. В ходе реструктуризации была выполнена работа по разделению определений типов и API для разных подсистем ядра.
Среди внесённых изменений: отделение высокоуровнневых заголовочных файлов друг от друга, исключение связывающих заголовочные файлы inline-функций, выделение заголовочных файлов для типов и API, обеспечение обособленной сборки заголовочных файлов (около 80 файлов имели мешающие сборке непрямые зависимости, выставляемые через другие заголовочные файлы), автоматическое добавление зависимостей к файлам “.h” и “.c”, пошаговая оптимизация заголовочных файлов, использование режима “CONFIG_KALLSYMS_FAST=y”, выборочная консолидация Си-файлов в сборочные блоки для снижения числа объектных файлов.
В итоге, проделанная работа позволила на 1-2 порядка сократить размер заголовочных файлов, обрабатываемых на стадии постпроцессинга. Например, до оптимизации использование заголовочного файла “linux/gfp.h” приводило к добавлению 13543 строк кода и подключения 303 зависимых заголовочных файлов, а после оптимизации размер сократился до 181 строк и 26 зависимых файлов. Или другой пример: при препроцессинге файла “kernel/pid.c” без патча подключается 94 тысяч строк кода, большая часть которого не используется в pid.c. Разделение заголовочных файлов позволило снизить объем обрабатываемого кода в три раза, сократив число обрабатываемых строк до 36 тысяч.
При полной пересборке ядра командой “make -j96 vmlinux” на тестовой систем применение патчей показало сокращение времени сборки ветки v5.16-rc7 с 231.34 до 129.97 секунд (с 27.7 до 15.5 сборок в час), а также повысило эффективность использования ядер CPU во время сборки. При инкрементальной сборке эффект от оптимизации ещё более заметен – время повторной пересборки ядра после внесения изменений в заголовочные файлы сократилось в разы (от 112% до 173% в зависимости от изменяемого заголовочного файла). Оптимизации пока доступны только для архитектур ARM64, MIPS, Sparc и x86 (32- и 64-бит).