Linuxカーネルとカーネル内のCFSスケジューラーについて読んでいます。CFS スケジューラの背後にあるコア コンセプトであるvruntime (仮想ランタイム)に出会いました。「<em>Linux Kernel Development」やインターネット上の他のブログを読みましたが、vruntimeの背後にある基本的な計算を理解できませんでした。vruntimeは特定のプロセスに属していますか、それとも同じ nice 値を持つプロセスのグループに属していますか。加重係数とは何ですか? また、その計算方法は? 私はこれらすべての概念を経験しましたが、理解できませんでした。また、 vruntimeと *min_vruntime*の違いは何ですか?
2 に答える
vruntime はスレッドごとです。これは、task_struct 内にネストされたメンバーです。
基本的に、vruntime はスレッドの「実行時間」、つまりスレッドがプロセッサで費やした時間の尺度です。CFS の要点は、すべての人に公平であることです。したがって、アルゴの種類は単純なものに要約されます。(特定のランキューのタスクの中で) vruntime が最も低いタスクが、実行する価値のあるタスクであるため、「次」として選択します。(実際の実装は、効率のために rbtree を使用して行われます)。
優先度、nice 値、cgroup などのさまざまな要因を考慮すると、vruntime の計算は、単純なインクリメントほど単純ではありません。「Professional Linux Kernel Architecture」、Mauerer、Wrox Pressの関連セクションを読むことをお勧めします。詳細に説明されています。
以下に、これのいくつかを要約するための簡単な試みを示します。
その他のリソース: Documentation/scheduler/sched-design-CFS.txt
簡単な要約 - vruntime の計算: (本に基づく)
ほとんどの作業は kernel/sched_fair.c:__update_curr() で行われます
タイマー刻みで呼び出されます
「現在」がプロセッサで費やした物理時間と仮想時間を更新します
デフォルトの優先度 (nice 値 0) で実行されるタスクの場合、費やされる物理時間と仮想時間は同じです。
他の優先度 (nice) レベルのタスクではそうではありません。したがって、vruntime の計算は、負荷の重み係数を使用して current の優先度の影響を受けます。
delta_exec = (unsigned long)(今 – curr->exec_start); // ... delta_exec_weighted = calc_delta_fair(delta_exec, curr); curr->vruntime += delta_exec_weighted;
いくつかの丸めとオーバーフロー チェックを無視して、calc_delta_fair が行うことは、次の式で与えられた値を計算することです。
delta_exec_weighed = delta_exec * (NICE_0_LOAD / curr->load.weight)
問題は、より重要なタスク (nice 値が低いもの) ほど重みが大きくなるということです。したがって、上記の式により、それらに計上される vruntime は小さくなります (したがって、rbtree の左側により多くエンキューされます!)。