Decennia aan coderommel opruimen is niet voor bangeriken, maar de toonaangevende Linux-kernelontwikkelaar Ingo Molnar geeft het de oude school een kans in de open-source Linux-kernel. Deze ontwikkelaar stelt 2.200 commit-wijzigingen voor.

Vorig jaar kwam de broncode van Linux uit op maar liefst 27,8 miljoen regels code. Het is sindsdien alleen maar groter geworden. Zoals elk 30 jaar oud softwareproject heeft Linux in de loop der jaren een behoorlijk deel van de cruft opgepikt. Nu, na maanden werk, geeft senior Linux-kernelontwikkelaar Ingo Molnar zijn eerste poging om het op een fundamenteel niveau op te schonen met zijn “Fast Kernel Headers”-project.

Het object? Niet minder dan een uitgebreide opschoning en herwerking van de header-hiërarchie en header-afhankelijkheden van de Linux-kernel. Linux bevat veel header-, .h-bestanden. Om precies te zijn zijn er ongeveer 10.000 hoofd .h-headers in de Linux-kernel met de hiërarchieën include/ en arch/*/include/. Zoals Molnar uitlegde: “In de afgelopen 30+ jaar zijn ze uitgegroeid tot een gecompliceerde en pijnlijke reeks van wederzijdse afhankelijkheden die we liefkozend ‘Dependency Hell’ noemen.”

Om dit alles rijm en reden te geven, stelt Molnar voor om 2.200 commit-wijzigingen in de code aan te brengen. Dat zijn veel verplichtingen! Waarom zo veel? Nou, vervolgde Molnar, het blijkt dat er veel meer rommel in al die code zit dan hij dacht toen hij eind 2020 aan zijn opruimproject begon. Om precies te zijn:

Toen ik eind 2020 aan dit project begon, verwachtte ik dat er misschien 50-100 patches zouden zijn. Ik deed een paar ruwe metingen die suggereerden dat een verbetering van de bouwsnelheid van ongeveer 20% kon worden bereikt door de afhankelijkheden van de header te verminderen, zonder een substantieel runtime-effect op de kernel te hebben. Leek substantieel genoeg om 50-100 commits te rechtvaardigen.

– Maar naarmate het aantal patches toenam, zag ik slechts beperkte prestatieverbeteringen. Medio 2021 kreeg ik meer dan 500 commits in deze boom en moest mijn tweede poging (!), weggooien, de eerste twee benaderingen schaalden gewoon niet, waren niet onderhoudbaar en boden amper een build-versnelling van 4%, niet de moeite waard de churn van 500 patches en niet eens de moeite waard om aan te kondigen.

– Met de derde poging introduceerde ik de per_task()-machinerie die de nodige flexibiliteit bracht om afhankelijkheden drastisch te verminderen, en het was een type-schone benadering die de onderhoudbaarheid verbeterde. Maar zelfs bij 1.000 commits kwam ik amper tot een verbetering van de buildsnelheid van 10%. Nogmaals, dit was niet iets dat ik op mijn gemak voelde om stroomopwaarts te duwen of zelfs maar aan te kondigen. :-/

– Maar de cijfers waren vrij duidelijk: 20% prestatiewinst was heel goed mogelijk. Dus ik bleef deze boom ontwikkelen, en de meeste versnellingen kwamen binnen na meer dan 1.500 commits, in de herfst van 2021. Ik was zeer verrast toen het verder ging dan 20% versnelling en meer dan de huidige 78% bereikte met mijn referentieconfiguratie. Er is een duidelijke superlineaire verbeteringseigenschap van kernel-build-overhead, zodra het aantal afhankelijkheden tot het absolute minimum is teruggebracht.

Dus vandaag biedt zijn opgeschoonde “fast-headers tree een verbetering van +50-80% in absolute kernel-buildprestaties op ondersteunde architecturen, afhankelijk van de configuratie. Dit is een grote stap voorwaarts in termen van efficiëntie en prestatie bij het bouwen van Linux-kernels .”

Een verbetering van 50 tot 80% is de tijd en moeite zeker waard. Deze snelheidsbesparingen zijn het gevolg van het verkleinen van de grootte van de standaard headers, die met de fast-headers-boom meestal typedefinities zullen bevatten, met 1-2 ordes van grootte. 

Maar wacht, die 2.200 commits zijn slechts het topje van de ijsberg. Die veranderingen zijn van invloed op bijna elk programma in de Linux-kernel. Alles bij elkaar schat Molnar dat “naast de bovengenoemde 25 sub-trees en 2.200 commits, de fast-headers tree meer dan de helft van alle bestaande kernelbronbestanden wijzigt.” Het gaat 25.288 bestanden veranderen met 178.024 toevoegingen en 74.720 verwijderingen. Met andere woorden: “Ja, dus dit is waarschijnlijk de grootste aankondiging van één functie in de geschiedenis van [Linux Kernel Mailing List] van LKML. Niet uit vrije wil! :-/”

Bovendien vereist het om deze wijzigingen uitvoerbaar te maken een agressieve ontkoppeling van headers op hoog niveau; type en API-header ontkoppeling; geautomatiseerde toevoeging van afhankelijkheid aan .h- en .c-bestanden; en het optimaliseren van kopteksten. Dit zal niet gemakkelijk zijn. Dus, voordat hij de trekker overhaalt en deze veranderingen begint aan te brengen, verzamelt Molnar feedback van zijn mede-beheerders en in het bijzonder zou hij graag horen van “Linus [Torvalds] & Andrew [Morton] en de andere beheerders van de grootste subsystemen beïnvloed door deze veranderingen.”

Greg Kroah-Hartman, de Linux-kernelonderhouder voor de stabiele Linux-tak, denkt: “Dit is ‘interessant’, maar hoe ga je de definitie van kernel/sched/per_task_area_struct_defs.h en struct task_struct_per_task synchroon houden?” Kortom, wie mag de kat aanbellen om al deze veranderingen in stand te houden? 

Molnar antwoordde dat hij bereid is om deze klus te klaren en dat hij denkt dat het niet zoveel moeite zal zijn. Kroah-Hatman zegende Molnars inspanningen en merkte op: “Ik laat dit allemaal over aan de ontwikkelaars van de planner, maar het ziet er nog steeds vreemd uit. De puinhoop die we creëren door problemen in C te omzeilen :)”

Hij is niet verkeerd. Dit is een van de redenen waarom er pogingen worden ondernomen om de tweede taal van Rust Linux te maken 

Als het wordt aangenomen, zullen gebruikers geen echte veranderingen zien. Maar Linux-kernel- en distro-ontwikkelaars zullen Linux sneller dan ooit kunnen compileren. Het resultaat zal zijn dat het eenvoudiger en sneller dan ooit is om verbeteringen, patches en functies aan Linux aan te brengen.