Portál AbcLinuxu, 1. května 2025 09:26
Analýza vlivů několika variant preemptivního jádra na časové odezvy procesů reálného času. Srovnání hard real-time linuxových modifikací (RTLinux, RTAI). Praktická aplikace.
1. ÚVOD
1.1 Co je to Linux
1.2 Probírané linuxové real-time modifikace
1.2.1 RTLinux
1.2.2 RTAI/fusion
1.2.3 Realtime preempt patch
2. RTLINUX
2.1 Úvod
2.2 POSIX
2.2.1 Základní pojmy
2.2.2 Plánování
2.2.3 Posixio
2.2.4 Signály
2.3 Shrnutí
3. RTAI
3.1 Úvod
3.1.1 Úvod do RTAI/fusion
3.2 Časovače a přerušení
3.3 Základní koncepty
3.4 Software
3.5 Podporované architektury
4. REALTIME PREEMPT MODIFIKACE JÁDRA
4.1 Souběžnost v jednoprocesorovém jádře
4.1.1 Kritické úseky a jejich správa
4.2 Souběžnost na SMP jádře a správa kritických úseků
4.2.1 Ochrana před jinými vlákny
4.3 Analýza prodlev preemptivního jádra
4.3.1 Prodlevy přerušení
4.3.2 Prodlevy závislé na úlohách
4.3.3 Shrnutí
4.4 Plně preemptivní real-time jádro
4.4.1 Vylepšení real-time zpracování úloh
4.4.2 Nezávislost kritických úseků
4.4.3 Nahrazování Spinlocku
4.4.4 Shrnutí
4.4.5 Vlastnosti Real-Time jádra
4.5 Real-time mutex
4.5.1 Dědičnost priorit
4.6 Benchmarky
4.6.1 Interbench
4.7 Shrnutí
5. APLIKACE
5.1 Embedded systémy a jiné aplikace pro řízení
5.2 Multimediální aplikace - JACK
6. ZÁVĚR
V nových jádrech řady 2.6 se objevilo mnoho vylepšení reagujících na požadavky embedded systémů, včetně nového plánovače a preemptivního jádra.
Od jader této řady se toho, na základě pokroků v technologii plánování, očekávalo hodně.
Nový plánovač sice dosahoval dobrých výkonů, ale odezva byla trvale znehodnocována prodlevami, když úlohy přistupovaly ke sdíleným systémovým datům uvnitř kritického úseku.
Počáteční měření ukázala, že jádra řady 2.6 v preemptivním výkonu zaostávala za řadou 2.4. Taky ve zpracování audia překonávala jádra 2.4 některé rané verze 2.6.
Během operací prováděných jádrem jsou sdílená data, porty a jiné hardwarové registry předmětem současného přístupu mnoha vlákny a rutinami obsluhujícími přerušení.
Kritický úsek je část chráněného kódu, se kterým může operovat pouze jedna úloha, aby se zajistila integrita sdílených dat. Každý proces běžící v kritickém úseku musí tento opustit. Teprve pak je povolen přístup jinému procesu.
Souběžné přístupy do sdílených objektů jsou seřazovány podle hranic kritických úseků, a tak je za všech okolností zajištěna stabilita sdílených dat a operací s hardwarovými registry.
V jádře existují dva základní typy kritických úseků:
První a nejjednodušší druh kritického úseku potlačuje přepínání úloh pokud vlákno provádí operace uvnitř kritického úseku. Tato vlastnost zajišťuje, že vlákno může tento úsek opustit před tím, než je povolen přístup jinému vláknu.
Před tím, než vlákno přistoupí k datům sdíleným s rutinou obsluhující přerušení, jsou přerušení vypnuta a znovu jsou zapnuta až po dokončení aktualizace těchto dat. To chrání data před souběžným přístupem rutinou obsluhující přerušení poté, co vykonávající vlákno vstoupilo do kritického úseku.
Pro základní správu kritických úseků v jednoprocesorovém prostředí jsou mechanismy preempt disable a interrupt disable postačující.
V jednoprocesorovém prostředí na CPU vykonává operace pouze jedno vlákno, a to tak dlouho, dokud neopustí CPU samo, nebo je k tomu donuceno výjimkou procesoru jako třeba přerušením.
Správa souběžnosti na SMP (symetric multiprocessing) jádře je výrazně komplexnější záležitost než je tomu u jednoprocesorového jádra, protože pouhé vypnutí preemptivity a přerušení už na ochranu dat sdílených procesory nestačí. To proto, že úlohy běžící na jiných procesorech nebudou vědět, jestli jsou tyto volby na CPU vypnuty, a mohou tak vstoupit do stejného kritického úseku zároveň. Z tohoto důvodu je nutné fyzicky alokovat sdílené zámky, které řídí přístup k jednotlivým kritickým úsekům. Tyto zámky, které chrání přístup do kritických úseků, se nazývají spinlock. Jsou alokovány v paměti a identifikují kritické úseky asociované se specifickými sdílenými daty. Tato architektura odděluje uzamykání pro nezávislá data. To dovoluje, aby mnoho vláken najednou mohlo pracovat v mnoha kritických úsecích jádra.
Když úloha získá spinlock, je jí umožněn vstup do kritického úseku a je také zabráněno přepínání úloh v procesoru, dokud neproběhne spin unlock. Během držení spinlocku mohou být vypnuta přerušení (Gerum, P.).
Ochrana před vlákny a přerušeními je, až na několik rozdílů, obdobná jako u jednoprocesorové implementace.
Pokud vlákno v jádře SMP systému narazí na spinlock, vyvstane situace, kdy bude úloha usilovat o uzamčení a přístup do kritického úseku, který již bude blokován jinou úlohou. Vlákno usilující o přístup bude aktivně čekat (točit se na místě - spin) na uvolnění uzamčení (lock). Odtud plyne anglický název "spinlock".
Pokud tedy bude vlákno na daném CPU aktivně čekat, nebude to CPU provádět žádnou práci.
SMP implementace má vztah k plně preemptivnímu real-time jádru, protože jakýkoliv SMP kód je v principu plně preemptivní.
Prodlevy preemptivity linuxového jádra řady 2.6 jsou složeny ze dvou hlavních prvků:
Zpracováním přerušení může být vlákno pozdrženo tak dlouho, dokud se tato operace nedokončí. Také procesy se po tuto dobu nemohou přepínat.
Prodlevy způsobené zpracováním přerušení mají 3 podskupiny:
* Rutina obsluhující přerušení by měla být vykonána co nejrychleji a zároveň musí vykonat mnoho práce. Kvůli tomu se zpracování přerušení dělí na dvě části, tzv. poloviny. Samotná rutina obsluhující přerušení tvoří horní polovinu. Ta se spustí hned po přijetí přerušení a představuje jenom práci, která je časově kritická, jako je např. poslání potvrzení o přijetí přerušení nebo reset hardware. To, co se může vykonat později, je zahrnuto v dolní polovině. Ta proběhne později, když jsou všechna přerušení povolena.
V linuxovém jádře je přes 10000 nezávislých kritických úseků. Jejich identifikace je časově náročná a vyžaduje důkladné testování a analýzu.
Omezování nejdelších kritických úseků je náchylné na chyby.
Podstatné zvýšení výkonu zpracování přerušení týkající se prodlevy preemptivity není dost dobře možné.
Je nerozumné optimalizovat nepreemptivní kritické úseky jeden po druhém pro zlepšení preemptivity úloh.
Pro výrazné zvýšení preemptivního výkonu linuxového jádra je potřeba prozkoumat původní principy návrhu, jelikož se týkají zpracování přerušení a správy kritických úseků.
U přerušovacího real-time subsystému je požadováno, aby vykonávání přerušení bylo upřednostnitelné (preemptible), aby dodržovalo priority, aby tyto priority přerušení byly alokovatelné na úlohové úrovni (tasklevel) v prostoru priorit a musí být možné povýšit prioritu real-time úloh nad zpracování přerušení.
Nepředvídatelná zpoždění způsobená zpracováním přerušení jsou vyřešena přesunutím zpracování přerušení do kontextu k tomu vyhrazených úloh. Těmto úlohám lze pak přiřadit libovolné priority.
Pouhým přesunutím softIRQ přerušovací aktivity a hardIRQ zpracování signálů do prostoru úloh (task space) nemůže být dosaženo žádných velkých zlepšení prodlev preemptivity na úlohové úrovni (tasklevel). K tomu je nutné snížit celkovou velikost a počet nepreemptivních kritických úseků.
Principy návrhu plně preemptivního real-time linuxového jádra jsou založeny na rozšíření konceptů zpracování a zamykání, které již byly použity u SMP jádra (Gerum, P.).
Kritické úseky jsou označeny unikátními jmény, a tak mohou v SMP za jistých podmínek CPU souběžně používat různé nezávislé kritické úseky. Tyto úseky mohou být chráněny alternativním uzamykacím mechanismem známým pod jménem mutex. To zajistí integritu dat a zároveň rozšíří spinlock operace v některých klíčových aspektech:
Pokud úlohy operují mimo kritické úseky, je linuxové jádro řady 2.6 už preemptivní. Nahrazení nepreemptivních spinlocků mutexy dovolí upřednostňování úloh uvnitř kritických úseků s real-time charakteristikami:
Odkládání zpracování přerušení do prostoru úloh a náhrada nepreemptivní implementace spinlocku mutexem více zatěžují CPU, ale to je cena za přizpůsobení preemptivního plánování úloh a přeměnu univerzálního linuxového jádra ve vysoce preemptivní, protože plánovač zde může dát přednost kterémukoliv vláknu, i když se toto nachází přímo v kritickém úseku.
Návrh plně preemptivního linuxového jádra je založen na funkčním rozšíření nepreemptivních uzamykacích vlastností SMP jádra. Následně uvedený datový typ RT-Mutex poskytuje základ kompletní preemptivity, dědičnost priorit a detekci blokování.
Robustností implementace SMP v linuxovém jádře, které již garantuje časovou nezávislost a správný chod v prostředí souběžných operací, se výrazně zjednodušuje real-time problém.
Real-time mutex na jednoprocesorovém jádře umožňuje běh mnoha vláken v mnoha různých kritických úsecích.
Aby byla zredukována zpoždění způsobená aplikacím s vysokou prioritou, které se pokoušejí přistupovat ke kritickým úsekům a které již byly uzamčeny úlohou s nižší prioritou, byl původní real-time mutex vylepšen o dědění priorit.
Dědičnost priorit zvyšuje prioritu úlohy, která byla během práce v kritickém úseku předběhnuta na nejvyšší úroveň ze všech úloh čekajících na přístup do téhož kritického úseku.
Tranzitivní dědičnost priorit dovoluje vláknu s nejvyšší prioritou uplatnit prioritu přes více úrovní závislostí kritických úseků.
Realtime preempt - patch vytvořený Ingo Molnarem nabízí 4 úrovně preemptivity:
Pro testování byla zkompilována 4 jádra verze 2.6.14. Pro každou úroveň preemptivity jedno. Tato jádra byla zkompilována ze stejnými parametry vyjma již zmíněné úrovně preemptivity.
Na testování prodlev byl použit pro tento účel vyvinutý program Interbench (volně ke stažení na http://members.optusnet.com.au/ckolivas/interbench/), který simuluje různé druhy zátěže v reálném čase a měří prodlevu při jejich vykonávání. Testování bylo provedeno v runlevelu 1, kdy běžely pouze nutné procesy, a počítač tak nebyl zatěžován dalšími úlohami, jež by znehodnocovaly výsledky testů.
Pro testování v režimu reálného času byl program spuštěn s parametrem
-r
. Během této sady testů se prováděl i Hack test, který byl ale natolik náročný, že způsobil pád programu. Aby se tento test neprováděl, byl vypnut parametrem -x Hack
. Výsledný příkaz, kterým byl program spuštěn, tedy byl ./intebench -r -x Hack
.
Typy zátěží simulované programem interbench:
Byla testována schopnost všech 4 variant jádra reagovat na požadavek o vykonávání úlohy za současného běhu jiné zátěže. Pro real-time benchmark se hodí zátěž zpracováním multimédií, protože se dá dobře nasimulovat a testovat. Třeba zatížení při softwarovém renderingu by v real-time oblasti nedávalo příliš smysl a neotestovalo by požadované vlastnosti jádra.
Z testů je patrno, že průměrná prodleva (světle šedé hodnoty) i maximální prodleva (tmavě šedé hodnoty) Real-Time varianty je překvapivě nejvyšší. Dá se to vysvětlit tak, že jak již bylo zmíněno, úpravy jádra jsou postupně přejímány do původního kódu jádra. Tím jsou výrazně omezeny jeho dřívější nedostatky. Zároveň se u této varianty projevila vyšší náročnost na výkon, což se negativně projevilo na výsledné prodlevě. Na druhou stranu by Real-Time varianta měla lépe garantovat splnění úlohy běžící v real-time režimu bez ohledu na to, jak je CPU zatíženo, a měla by být lépe předvídatelná.
Vývoj této úpravy linuxového jádra dosáhl takové úrovně, že může konkurovat předcházejícím dvěma řešením a to jak nekomerčnímu RTAI, tak komerčnímu řešení RTLinux.
Navíc byla nedávno přidána vylepšená implementace časovačů jádra (Ktimers). To umožňuje real-time úlohám vzájemně spolupracovat s velmi nízkou prodlevou s vysoce výkonnými časovacími zařízeními s jemným rozlišením. Ty umožňují implementaci řídících smyček v reálném čase s nebývalou přesností. Taky je umožněno použití RT mutexu v uživatelském prostoru přes standardní kernel API. Také úlohy v uživatelském prostoru jsou schopny využít efektivní dědičnosti priorit, detekce uváznutí a robustních protokolů pro jejich odblokování.
Z výše zmíněných informací je zřejmé, že takto koncipované řídicí systémy najdou uplatnění v různých aplikacích. Jsou to zejména zapouzdřená (embedded) zařízení a taky zpracování zvuku a videa. Mimo to parametry real-timové verze Linuxu dovolují používat tento operační systém jako prostředek pro modelování a simulaci různých jevů.
Real-time modifikace Linuxu je možno využít pro ovládání různých elektronických zařízení a jako Embedded zařízení.
Embedded systémy jsou takové systémy, které jsou vestavěné do různých zařízení. Mezi vlastnosti, které může Linux nabídnout těmto kategoriím, patří:
JACK je audio server s nízkou prodlevou běžící na Linuxu a jiných systémech vyhovujícím normě POSIX. Může propojit několik různých audio aplikací a taky jim umožnit vzájemné sdílení audio dat. Tyto aplikace (klienty) mohou běžet ve vlastních procesech jako normální aplikace nebo jako plugin uvnitř serveru JACK. JACK byl od základu navržen pro profesionální práci s audiem a jeho design se zaměřuje na dvě klíčové oblasti: synchronní běh všech klientů a operace s nízkou prodlevou.
Všechny tři varianty podávají obdobný výkon. Je jenom na tvůrci systému, které variantě dá přednost (pouze realtime preempt ještě není úplně dokončená a vyladěná úprava). Nejzásadnější rozdíly jsou ve způsobu implementace real-time úpravy a ceně produktu.
RTLinux je komerční řešení a všechny real-time úlohy běží jako moduly v real-time jádře a používají jeho API. Proto se pro něj jinak programují aplikace. Naproti tomu pro Realtime preempt se úlohy programují jako pro původní Linux, protože tyto volají standardní linuxové API.
RTLinux a RTAI se navíc, na rozdíl od realtime preempt, který se stále ještě vyvíjí, už nasazují na real-time zařízeních.
Linux samotný má řadu výhod. Mezi nejvýznamnější patří:
Celá oblast se nadále rozvíjí a výše zmíněné systémy jsou dále vyvíjeny a zdokonalovány. Samozřejmě také narůstá počet aplikací, kde je možné využít takto koncipované real-timové operační systémy.
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.