A Linux processz ütemező II.

Címkék

(A cikksorozat első része itt.)

Időszelet

-----------

Az időszelet egy olyan numerikus érték, amely meghatározza, hogy egy taszk mennyi ideig futhat, mielőtt a preemptálás bekövetkezik. Az ütemező irányelv (scheduler policy) határozza meg az alapértelmezett időszelet nagyságát. Ez nem könnyű feladat. A túl hosszú időszelet a rendszer gyenge interaktív teljesítményét okozhatja; a rendszert használó felhasználóban nem alakul ki az az érzés, hogy a programok párhuzamosan futnak. Ha viszont az időszelet túl rövid, akkor jelentős lesz az elvesztegetett processzoridő, mert a gyakori processzek közti kapcsolgatás jelentős overhead-del jár. Ebben az esetben a rendszer jelentős időt fordít arra, hogy gyakran kapcsolgat az éppen futó processzről a következő futtatandó processzre és vissza. Tehát az ütemezőnek meg kell találni a középutat a túl hosszú és a túl rövid időszelet között. Mindezt úgy, hogy a CPU függő és az I/O függő processzeknek is jó legyen. Az I/O függő processzek nem igényelnek hosszú időszeleteket, míg a processzor függő processzek hosszú időszeletekért könyörögnek (például azért, hogy a gyorsítótáraikat (cache) ``forrón'' tartsák).

Ennek fényében azt a következtetést vonhatjuk le, hogy a hosszú időszelet rosszabb interaktív teljesítményt ad. Számos operációs rendszeren ezen a megfigyelésen alapult az ütemező tervezése. Ezekben az operációs rendszerekben az alapértelmezett időszelet viszonylag kicsi, például 20 millisec.

A Linux kihasználja azt az előnyt, hogy a magasabb prioritási értékkel rendelkező processzek mindig futnak. A Linux ütemező felnyomja az interaktív processzek prioritását, és engedélyezi számukra, hogy gyakrabban futhassanak. A Linux ütemező - összehasonlítva más rendszerekkel - relatíve magas alapértelmezett időszelet értéket ad (a 2.6.0-test11 kernelben a minimum timeslice 10ms, az alapértelmezett 100ms, és a maximum 200ms - kernel/sched.c). Továbbá a Linux ütemező dinamikusan, a prioritás alapján határozza meg a processz időszeletét. Ez lehetővé teszi, hogy a magasabb prioritással rendelkező, fontosabb processzek hosszabb ideig és gyakrabban futhassanak. A dinamikus időszelet és prioritás implementálása robosztus ütemezési teljesítményhez vezet.Megjegyzendő, hogy a processzek nem használják fel egyszerre a rendelkezésükre álló processzoridőt. Például, egy olyan processz, amely 100 millisec időszelettel rendelkezik, nem fog 100 millisec időt futni egyszerre, kockáztatva ezzel, hogy azonnal elveszíti a futási jogát. Helyette inkább ötször újraütemeződik, és 5 x 20 millisec időt fut. Ily módon a nagyobb időszelet kedvez az interaktív processzeknek is - mert nem kell felhasználniuk a nagy időszeletet egyszerre, viszont a nagyobb időszelet biztosítja számukra, hogy futhassanak olyan hosszan amilyen hosszan az lehetséges.

Vajon mi történik olyankor, ha a processz felhasználja az egész időszeletét? Ha a processz időszelete letelik, akkor a processzt lejártnak (expired) tekinti az ütemező. Az a processz amelyik nem rendelkezik időszelettel, nem futhat egészen addig, amíg az összes processz időszelete le nem telik (azaz, amíg az összes processznek 0 nem lesz a megmaradt időszelete). Ezen a ponton az összes processz időszelete újrakalkulálódik. A Linux ütemező egy érdekes algoritmust alkalmaz annak érdekében, hogy az időszelet felhasználást kezelje. Erről majd később.

(Megjegyzés: Az időszeletet hívják más rendszereken quantum-nak és processzor szeletnek is. A Linux időszeletnek hívja.)

Processz preemptálás

-------------------------

Mint említettem, a Linux operációs rendszer preemptív. Amikor a processz a TASK_RUNNING állapotba lép, a kernel ellenőrzi, hogy a prioritása magasabb-e az éppen végrehajtás alatt álló processz prioritásánál. Ha igen, akkor az ütemező felveszi a processzt és futtatja. Továbbá, amikor a processz időszelete lejár (eléri a 0-át), akkor preemptálódik, akkot az ütemező egy másik processzt fog kijelölni futtatásra.

Az ütemezési irányelv akcióban

------------------------------------

Tételezzünk fel egy olyan rendszert, ahol két futtatandó taszk van. Az egyik egy szövegszerkesztő, a másik egy video enkóder. A szövegszerkesztő I/O függő, mert idejének legnagyobb részét azzal tölti, hogy a felhasználó billentyű leütéseire vár (az nem lényeges ebből a szempontból, hogy ki milyen gyorsan tud gépelni). Feltételezzük azt, hogy amikor a felhasználó leüt egy billentyűt, akkor azt szeretné, hogy a szövegszerkesztő azonnal reagáljon, és jelenítse meg a kívánt karaktert, vagy tegye egyéb dolgát. A szövegszerkesztővel ellentétben a video enkóder processzor függő. Attól eltekintve, hogy felolvassa az adat folyamot a diszkről, majd később kiírja a lemezre, ideje nagy részét azzal tölti, hogy a video kodeket alkalmazza az adatra. Itt a dolog nem időkritikus olyan szepmpontból, hogy mikor kezdődik el az enkódolás (millisec-ekben gondolkodjuk!), most vagy fél másodperccel később. Ezt a felhasználó nem veszi észre. Természetesen minél előbb, annál jobb.

Ezen a rendszeren az ütemező magasabb prioritást és nagyobb időszeletet ad a szövegszerkesztőnek, mint a video enkódernek, mert a szövegszerkesztő interaktív. A szövegszerkesztőnek bőséges időszelet áll rendelkezésére. Mivel a szövegszerkesztő magasabb prioritással rendelkezik, mint a video enkóder, lehetősége van preemptálni a video enkódert, ha az szükséges (pl. billentyű leütésnél). Ez biztosítja azt, hogy billentyű leütésre a szövegszerkesztő azonnal reagálhasson akkor is, ha a video enkóder fut. Ez a működés egy kicsit hátrányos a video enkódernek, de az a tény hogy a szövegszerkesztő csak váltakozva fut, lehetővé teszi a video enkóder számára, hogy kisajátíthassa a maradék időt. Ily módon biztosítja az ütemező mindkét alkalmazás maximális teljesítményét.

Folytatása következik.

Az írás Robert M. Love hasonló című írásán alapul.