Linux 2.6 Schedulerの挙動の研究 Brought to you by: キム デウン 澤井 省吾 弘中 健 Linux Kernel Sched. 2.4の復習 各スレッド(プロセス)は定めされた時間間隔 (“counter”)だけCPUを使ってよい。 10ms毎にtimer tickが実行され、現在走ってい るプロセスはcounter- -される。 counter→0になったプロセスはもう走れない。 Linux Kernel Sched. 2.4の復習 各”epoch”が始まる前に各プロセスのcounter が再計算される。 – – – 計算にはそのプロセスの「対話性値」(nice value)が 考慮される。 勿論、前epochで使い切れなかったcounterも考慮さ れる。 new_counter= old_counter/2+goodness(nice) Linux Kernel Sched. 2.4の復習 Schedule()によって次に走るべきプロセスが選 択される。 – – 実行可能なタスクの内、最大のcounterを持つものが 選択され、実行される。 Schedule()はtimer tickで呼ばれるか、もしくは各プロ セスがsched_yield()を使って呼ぶ。 非常に単純なアルゴリズムで宜しかった!! が。。。 Linux Kernel Sched. 2.4の復習 欠点:O(n)のスケジュラー – – – Epoch毎に全てのプロセスのcounterを再計算:O(n) 最大のcounter値を持つプロセスを見つけ、実 行:O(n) プロセスの数が多くなるとスケジュラーのせいで効率 が大幅に落ちる。 対話性の見積もりが雑。。。 – counterが大きいからと言って対話的プロセスではな い Linux Kernel Sched. 2.6での改善 O(1)スケジュラー – スケジュラーの処理時間はプロセスの数に無関係な 一定時間しか掛からない。 「対話性」の見積もりヒューリスティックスを改善 し、対話的プロセス優先をより正確に実現 対話的プロセスとは? “I/O-Bound”なプロセス 普段はスリープしていてCPUはあまり使わない が、要求に対して直ぐ走ることが求められるプロ セス。 「寝て。。。ちょっと走って、寝て。。。」 ⇔”CPU-Bound”なプロセス – 殆ど寝ずにCPUをがめようとするプロセス 2.6 Schedulerの構成 Runqueue – 1つのCPUに付き1つ Priority Array – 1つのrunqueueに対して2つ Active Array, Expired Array Runqueueとは? CPUの特別スレッド(idle thread, mitigation thread)の 管理 二つのpriority array(へのpointer)の管理 – – – 1つのpriority arrayに属するプロセスを実行して行く←Active Array それぞれのプロセスに割り当てられた時間(“Timeslice”)を使い 切ったプロセスはもう一方のpriority arrayに移される←Expired Array Active Arrayが空っぽになったらexpired/active arrayへのポイ ンタを交換して新しいarrayのプロセスを実行 Priority Arrayとは? 連結リストの配列 – – 配列長のビットマップ – 長さはプロセスの優先度の数(具体的には140個) 一つの配列の要素、つまり一つの連結リストに属するプロセス はすべて同じ優先度 ある配列要素にプロセスが存在すれば1が立つ、さもなければ0 O(1)アルゴリズムを可能にしているデータ構造 – – 定数時間で一番優先度(priority)が高いプロセスを検索すること が出来る。 定数時間で同じ優先度のプロセス同士のround-robin 一連の流れ Active Arrayの中で最優先priority levelをビットマップで 見つける(一番indexが小さい要素の連結リスト)。 その連結リストのプロセスを順に実行する Timesliceが使い終わったプロセスは新しいtimesliceが 与えられ、新しい優先度が計算され、Expired Arrayの 該当する優先度の要素のリストに移される。 Active Arrayにプロセスがなくなったら(全てExpired Arrayに移動した)Active Array⇔Expired Array 本当にO(1)アルゴリズム? 最も高いpriority levelを持つプロセスの検索= ビットマップ長の検索:O(1) 一つのプロセスをActive→ Expired Arrayに移 す:O(1) Active, Expired Arrayの交換:O(1) グラフィックな理解 Active Array Runqueue Expired Array 1 0 0 1 1 0 0 1 1 0 0 1 0 0 1 1 0 0 0 0 0 0 1 優先度の計算 理念 – Static Priority – – 対話的プロセスの優先度は高く、非対話的プロセス の優先度は低く 初期値は0 System call: nice(int prio)で変更か(-20~19) Dynamic Priority(priority array上の優先度) – Static Priority-Bonus Dynamic Priorityの計算(1) ヒューリスティック – Sleep timeが長いほど、run timeが短いほど大きい Bonus Sleep_avg(recalc_task_prio()で計算) – – – Sleepから復帰:sleep_avg+=sleep_time CPUを手放す時:sleep_avg-=run_time |sleep_avg|<=MAX_SLEEP_AVGとしてある Dynamic Priorityの計算(2) effective_prio(p):dynamic priorityの計算 – – – recalc_task_prio(p): – Bonus=MAX_BONUS*sleep_avg/MAX_SLEEP_AVGMAX_BONUS/2 prio=static_prio-bonus 初期値ではbonus=[-5,5] sleep_avgを再計算し、effective_prio(p)を実行 良く寝るプロセスほど優先的に走り、CPUをがめようとす るプロセスほど後回しになる。 TimeSliceの計算 一つのプロセスがActive→ Expiredになるまで に使っていいCPUの時間 Static Priorityによって決まる。 – Timeslice=MIN_TIME_SLICE+ (MAX_TIMESLICE+MIN_TIME_SLICE) *(MAX_PRIO-1-static_prio)/(MAX_PRIO-1) 対話的なプロセスの応答をさらに改善 ある程度以上の「対話性」を持つプロセス は”interactive”(対話的)とされる。 – – プロセスは普段はTimesliceを使い切るまでCPUを独 占できるが、TIME_GRANUALITYというさらに細か い時間粒子で、同じpriorityの連結リスト内でround robinでCPUを使う。 さらに、他のプロセスが長時間待たされていない限り、 (“starve”していない限り)timesliceを使い切っても、 Active Arrayに再び再挿入される! Schedulerの主な担い手 scheduler_tick() schedule() scheduler_tick() Timer 割り込みで1ms刻みで実行 現在走っているプロセスのtimeslice-現在走っているプロセスのtimeslice=0だったらそのプロ セスを退避させ(expired arrayに、interactiveな場合は active arrayに再挿入)、TIF_TASK_NEED_SCHEDフ ラッグを立て、schedule()が呼ばれるようにする。 InteractiveプロセスがTIME_GRANUALITY走ったら次 のプロセスに譲るように施す。 schedule() 寝るプロセスはrunqueueから外す。 Active Arrayの中から一番優先度の高いプロセ スを見つけ、CPUを今まで使っていたプロセスと context switchを行う。(CPU、メモリの交換) 主にscheduler_tick()によって呼ばれる。 プロセスが明示的にschedule()を呼んで、CPU を返上することも出来る。 scheduler_tick()とschedule()の関連 scheduler_tick()とschedule()の関連 scheduler_tick()はリスケジュールが必要な時 (タスクがtimesliceを使い切った、interactiveプ ロセスのRR)、フラッグを立ててschedule()が実 行されるようにする。 schedule()は次のプロセスを選び、CPU使用の 交代を行う。これをPreemptionと言う – 必ずしもscheduler_tick()で呼ばれなくてもよい、プロ セスが直接sched_yield(),schedule()を呼んでCPU を返上することも出来る。 Preemption 現在走っているプロセスがschedule()によって 他プロセスにCPUを返上すること。 基本的にTIF_TASK_NEED_RESCHEDフラッ グが立っている時 – – – Scheduler_tick()が呼んだ時 新しいプロセスがsleepから起きた時 System callが終了した時 Kernel Preemption Kernel 2.6で新しく登場 System Callなど、kernel modeで走っている時でもリス ケジュールフラッグが立っていればkernelは他のプロセ スにCPUを返上する。 Critical sectionを処理している時は? – – どうしてもpreemptされたくない時はlockを取得する。 preempt_count Lock取得preempt_count++ Lock開放preempt_count-preempt_count=0の時のみkernelはpreempt可能 Sleepする Runqueueから外れてCPUを一切使わない状態 に入る。 Interruptible/uninterruptible – – Interruptibleだとsignalで起こすことが出来る。 Uninterruptibleだとsignalには自分で起きるまで応答 しない。 Sleepするための手続き Waitqueueを作る – あるイベント・条件が満たされるまでプロセスたちが 待機している場所(runqueueの外) add_wait_queue() schedule()を呼んでCPUを返上する。 Wake Up!! Wait queueのすべてのプロセスに対して try_to_wake_up()が呼ばれる。 activate_task()で寝た分priorityがブーストされ、起こさ れるタスクがactive arrayによって追加される。 もし現在走っているプロセスよりも起きたプロセスの priorityが高かったらTIF_TASK_NEED_RESCHEDフ ラッグを立てて、schedule()を呼ぶ。 – – さもないとそのタスクがCPUを使えるチャンスは次にschedule() が呼ばれる以降。 恐らくscheduler_tick()が呼ばれないといけないから一回寝たら 大体の場合1ms以上走れないハメになる。 Real Time Processes スケジュラーも素晴らしいけど、待てない deadlineがある仕事もある! Soft Real-Time Scheduling – きっちりtime deadlineは守れないけど、努力する RT schedulingの実装 Priority:終わるまでCPUを使える。 – 140のpriority levelの内トップ0~99を占有 通常プロセスは100-139のレベルで、その枠を出れない RT policy – – RT FIFO RT RR Priority Array上の並び方構造 0 RT Prioirty 99 100(-20) User Priority 139(19) RT_FIFO Real Time First In First Out – – – – Timesliceなし! プロセスが完了するまでCPUを独占する。 より優先度が高いRT_FIFOプロセスが登場するとそ れにCPUを返上する。 基本的にscheduler_tick()が目をつぶっている。 「常識的設計」が求められる ;-) RT_RR Real Time Round Robin – – – – 完了するまで走ることには変わりない 同じpriority内で決まったtimeslice毎にround robinで 走る。 Priorityは固定される。(ペナルティを食らわない) 基本的にtimeslice=0になったらまた scheduler_tick()が新しいtimesliceを与えて、active arrayに戻す。 実験 お待たせしました。。。 System Calls #include <unistd.h>,<sched.h> **int nice(int inc); int sched_yield(void); **int sched_setparam(pid_t pid, const struct sched_param *param); **int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param); int sched_rr_get_interval(pid_t pid, struct timespec *interval); **suでないと設定出来ない値もある Bibliography: Aas, Josh. “Understanding the Linux 2.6.8.1 CPU Scheduler.” Feb. 17, 2005 – http://josh.trancesoftware.com/linux/ Fischer, Gordon.,Rodriguez, Claudia.,Salzberg, Claudia., Smolski, Steven., “Linux Scheduling and Kernel Synchronization.” Prentice Hall PTR. Nov. 11, 2005 – http://www.phptr.com/articles/article.asp?p=414983&seqNum=1&rl =1 Love, Robert. “The Linux Process Scheduler.” Nov. 13, 2003 – http://www.samspublishing.com/articles/article.asp?p=101760&seq Num=3&rl=1 Special Thanks 田浦先生 – – – 質問に根気強く答えてくれるだけでなく、積極的にイ ンプットを下さりました。 また、martenサーバーを実験用に使わせて下さいま した。 先生の助けがなくてはこの課題達成は不可能で、個 の場を借りて感謝をしたいと思います。
© Copyright 2024 ExpyDoc