linux程序排程 完全公平排程類

2021-06-17 17:47:14 字數 3282 閱讀 6561

完全公平排程類是排程類的乙個例項

static const struct sched_class fair_sched_class = ;
在主排程器和週期排程器中會根據程序型別呼叫完全公平排程類或者實時排程類的函式。

@next,指向空閒排程類,而實時排程類的next則指向完全公平排程類。這個順序在編譯之前已經建立好了,不會在系統執行時動態建立。

@enqueue_task_fair,向就緒佇列新增乙個新程序,在程序從睡眠狀態變為可執行狀態時,即發生該操作。

@dequeue_task,將乙個程序從就緒佇列去除,在程序從可執行狀態切換到不可執行狀態時,即發生該操作。雖然這裡稱為乙個佇列,但是內部的具體實現,完全是排程器類決定的。

@yield_task,程序可以通過系統呼叫sched_yield自動放棄執行,此時核心會呼叫排程器類的yield_task函式。

@check_preempt_curr,在必要的情況下,會呼叫這個函式來搶占當前的程序。

@pick_next_task,用於選擇下乙個即將執行的程序

@put_prev_task,在用另外乙個程序代替當前執行的程序之前呼叫

@set_curr_task,在當前程序的排程策略發生變化時呼叫,那麼需要呼叫這個函式改變cpu的當前task

@task_tick,在每次啟用週期性排程器時,由週期性排程器呼叫

@new_task,當系統建立新的task時,需要通過這個函式通知排程器類

資料結構

主排程器的每個就緒佇列中都嵌入了乙個該結構的例項:

230 /* cfs-related fields in a runqueue */

231 struct cfs_rq ;

nr_running計算了佇列上可執行程序的數目,load則維護了所有這些程序的累積值。我們會通過load來計算虛擬時鐘

exec_clock 僅具有統計做的實際執行時間。

min_vruntime計算了佇列上所有程序的最小虛擬執行時間。

tasks_timeline 是紅黑樹的樹節點,這棵紅黑樹管理所有程序,按照這些程序的虛擬執行時間進行排序,最左邊的程序是虛擬執行時間最小的程序,也是最需被呼叫的程序。

rb_leftmost 指向這棵樹最左邊的節點,實際上我們可以通過遍歷tasks_timeline找到這個節點。

curr 指向cfs_rq中當前可執行程序的排程實體

cfs工作原理

完全公平排程演算法依賴於虛擬時鐘,用以度量等待程序在完全公平系統中所能得到的cpu時間。但資料結構中並沒有虛擬時鐘的表示,這是因為虛擬時鐘可以通過實際時鐘,以及與每個程序相關的負荷權重計算出來。

所有和虛擬時鐘相關的計算都在update_curr中進行的,該函式在系統中各個不同的地方呼叫。

336 static void update_curr(struct cfs_rq *cfs_rq)

337

360 }

339 rq_of(cfs_rq)->clock 用於實現就緒佇列自身的時鐘,每次呼叫週期性排程器時,都會更新clock的值

350 curr->exec_start儲存了上次更改load時的時間,注意並不是程序的上一次執行時間。當前程序在一次執行過程中,可能會發生多次update_curr

__update_curr

304 static inline void

305 __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr,

306 unsigned long delta_exec)

307

320 curr->vruntime += delta_exec_weighted;

321

322 /*

323 * maintain cfs_rq->min_vruntime to be a monotonic increasing

324 * value tracking the leftmost vruntime in the tree.

325 */

326 if (first_fair(cfs_rq)) else

330 vruntime = curr->vruntime;

331

332 cfs_rq->min_vruntime =

333 max_vruntime(cfs_rq->min_vruntime, vruntime);

334 }

313 sum_exec_runtime 該程序消耗的cpu時間累積值,@delta_exec是上一次更新負荷統計量時兩次的差值,二者都是真實時間。

316 如果程序的優先順序為120(nice = 0),那麼虛擬時間和物理時間相同,否則通過calc_delta_mine計算虛擬執行時間

326 first_fait檢測樹上是否有最左邊的節點,即是否有程序在樹上等待排程

332 cfs_rq->min_vruntime是單調增加的

在執行過程中,程序排程實體的vruntime是單調增加的,優先順序越高的程序,增加的速度越慢,因此他們向右移動的速度也就越慢。這樣被排程的機會就越大。

延遲跟蹤

核心有乙個固有的概念,稱之為排程延遲,保證每個程序至少被執行一次的時間間隔。

sysctl_sched_latency

引數用來控制這個行為,預設定義為20ms,可以通過/proc/sys/kernel/sched_latency_ns來控制。

sched_nr_latency

控制在乙個延遲週期內處理的最大活動數目。如果活動程序的資料超過了該上限,則延遲週期也成比例的線性擴充套件。

__sched_period

__sched_period = sysctl_sched_latency * nr_running / sched_nr_latency

在乙個延遲週期內,通過考慮各個程序的權重,將延遲週期的時間在活動程序之間進行分配。對於有某個排程實體表示的給定程序,分配到的時間如下計算。

static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se)

完全公平排程

cfs定義了一種新的模型,它給執行佇列中的每個程序都設定了乙個虛擬時鐘,即vruntime。如果乙個程序被排程器投入執行,隨著時間的增長,其vruntime將不斷增大,而沒有得到執行的程序vruntime則不會發生變化。排程器總是選擇vruntime最小的那個程序來執行,這就是所謂的 完全公平 為了...

Linux 完全公平排程器

讀書筆記,linux 系統程式設計 第六章高階程序管理 linux排程器為完全公平排程器,簡稱為cfs。和最近華為鴻蒙提出的確定時延排程相反。完全公平排程器和傳統的unix排程器有很大的區別。在大多數unix系統中,包括引入cfs之前的linux系統,在程序排程中存在兩個基本的基於程序的因素 優先順...

完全公平排程 cfs

現代os都會把時間用 當量quanta 來表示。這樣的單位有助於對不同任務的管理和排程。os version tick freqency linux2.4 100hz linux2.6 above 100,250,300 or1000hz 更高的os具有可選的tick頻率,這種配置一般在開始階段配置...