完全公平排程 cfs

2021-07-05 05:11:43 字數 4901 閱讀 7694

現代os都會把時間用「當量quanta」來表示。這樣的單位有助於對不同任務的管理和排程。

os version

tick-freqency

linux2.4

100hz

linux2.6(above)

100,250,300 or1000hz

更高的os具有可選的tick頻率,這種配置一般在開始階段配置。一單系統起來了就不能再改了,在linux2.6.21之後,引入了dynamic tics可以在系統idle時候忽略tick-timer中斷的發生。

dynamic tic的新增、測試

在menuconfig中新增config_no_hz,在tickless system中。

檢視本地的kernel是否支援dynamic tic,可以如下:

#dmesg | grep -i nohz

switched to nohz mode on cpu #0

有如上字樣或者檢視睡眠時的timer次數是否是無規律了:

# cat /proc/interrupts | grep -i time

# sleep 10

# cat /proc/interrupts | grep -i time

process affinity

每個process都有乙個mask標誌哪個cpu可以用它。

重新再cpu間排程並不影響affinity。

2.1時間單位

cfs排程更需要精確的timer機制,需要ns解析度的timer。

2.1cfs情景

當乙個process用完其時間片,將其從active鍊錶移動到expire鍊錶。當active鍊錶元素用光了後,通過指標操作將active和expire鍊錶交換一下。

某個process的時間片長度依賴於其靜態優先順序和在queue中的index。

o(1) scheduler指無論有多少個processes,每次任務切換的時間都是一樣常量。

涉及方案:

item

policy

idle

(sched idle)

real-time

(sched fifo sched rr)

fair

(sched normal sched batch)

cfs的policy

item

cfs-policy

sched_normal

應用在normal process中

sched_batch

不允許程序搶占normal的process

2.2 cfs和o(1)的區別對比

優先順序

一般的schedule對process的優先順序的動態考量會依賴:每個task用cpu的時間和每個task等待cpu的時間。

cfs,不會依賴這些資料,而是僅僅看其靜態優先順序

鍊錶

一般的schedule

用2個鍊錶,乙個active,乙個passive。process全為passive中時,需要swap這兩個表。

cfs

用乙個紅黑樹來表徵。

時間片

o(1)採用當process用完其timeslice,從active到expire鍊錶時,會重新計算其timeslice。

cfs採用動態時間量子,一單process被選中,立即會計算其timeslice。

virtual time

上邊說了cfs是以乙個紅黑樹來獲得即將執行的process,該紅黑樹主要是以vruntime為鍵值的。把最小的vruntime放到

cfs的排程流程

當用cfs時,其排程有排程開始時、剛排程、排程後持續監聽

排程開始時:

會選擇「擁有最小vruntime」或者「最新生成的process」符合這兩個條件的程序來經cfs排程執行。

剛排程

該任務就占有cpu。

排程後持續監聽

每一次的timer interrupt中,核心都會

1、更新virtual runtime,而vruntime是在process一啟動就會開始記錄的。

2、以」current_vruntime - min_vruntime」作為key值存於cfs的排程紅黑樹中。將最小的vruntime放到紅黑樹的最左端。

當然,在某次timer interrupt中,發現滿足下面的幾個條件,即立即進入cfs排程:

1、該process用盡其時間片

2、存在比當前process還小的最小的vruntime的process

3、有新建的乙個process

4、某個process剛從sleep中醒來。

cfs提供給user一系列的控制介面可以調整其引數,通過proc檔案系統反映給user。

對其引數的讀寫可以有兩種方式:1、檔案讀寫;2、sysctl系統呼叫

# cat /proc/sys/kernel/sched_latency_ns

# sysctl sched_latency_ns

還可以# echo value > /proc/sys/kernel/sched_latency_ns

# sysctl -w sched_latency_ns=value

2015-9-10 23:51:33

sched_child_runs_first

1,子程序比父程序優先獲得cpu。

0,反之。

sched_compat_yield

0,阻止當前程序交出cpu

sched_wakeup_granularity_ns

值越大,「搶占」成功率越低

sched_migration_cost

當程序從睡眠中喚醒時,該位表示是否「此時」進行一次排程,預設0.5ms。如果當前正在執行的程序的current time和剛剛被喚醒的哪個程序的runtime的均值,小於sched_migration_cost,那麼排程器會選擇該剛剛喚醒的程序。核心配置中一定要開啟wakeup_overlap項。

多核條件下的scheduler

多核涉及乙個負載均衡問題。

sched_migration_cost

把task從乙個cpu0遷移到cpu1,需要看cpu0上的cache是否還有該task的資訊,如果有,那麼就不能把該task遷到cpu1。

該位表示任務在cpu間遷的代價,預設0.5ms。如果該cpu0上的任務的runtime值小於該sched_migration_cost,就表明cache還有東西,不能遷。

sched_nr_migrate

排程器能處理的任務數,預設32.

sched_rt_runtime_us

乙個實時任務的可占用cpu的最大的時間。用完時間後,必須讓出cpu

sched_rt_period_us

cfs排程器需要等待該值的時間才能再次排程runtime任務,這裡只說了runtime任務需要等待的時間。

cfs排程特性

操作/sys/kerenl/debug/sched_features

new_fair_sleepers

cfs中任何乙個被喚醒的task的vruntime都等於紅黑樹中最小的vruntime。

如果該位為yes,則不會是堆笑的vruntime,而是在其本身的值上減去sched_latency_ns,但不會小於其他的等待的task的vruntime

normalized sleeper

在上面基礎上,該為yes,則sched_latency_ns是個normal值。

wakeup_preempt

被喚醒的task立即搶占cpu。

start_debit

在為乙個新task的vruntime初始化時,如果該為yes,則其vruntime值會遞增乙個量,該量的值等於normalized timeslice。

sync_wakeups

同步喚醒任務。

hrtick

開關高解析度的timer

double tick

yes,中斷來自高解析度的timer**或**系統timer。

no,中斷僅來自高解析度的timer。

asym_gran

影響wake up的粒度值,為yes,sched_wakeup_granularity_ns 是normalized。

更多參考

documentation/scheduler/sched-design-cfs.txt

Linux核心 CFS 完全公平排程演算法

1.cfs的原理 cfs給每乙個程序安排乙個虛擬執行時鐘vruntime,當乙個程序得以執行,隨著時間的推移,vruntime的值不斷的增大。而沒有執行的程序的vruntime的是不會改變的。而排程器總是選擇程序佇列中vrutime最小的程序執行,這就體現了 完全公平性 那如何區分不同程序之間的優先...

完全公平排程

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

Linux 完全公平排程器

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