Linux CFS中的程式排程
使用優先順序對映時間片的劣勢
在Linux中用nice值代表優先順序,它的範圍是-20~19。nice值越低,優先順序越高。
在Linux之前,Unix中就是使用nice值對映時間片的方式來進行排程。比如,nice值為0對應100ms的時間片,nice值為20對應5ms的時間片,nice值為19對應10ms的時間片。
在一般情況下,如果是nice值為0和nice值為20的兩個程式同時執行,那麼他們對應的時間片分別為100ms和5ms。這種情況中,nice值為0的程式擁有20/21的處理器時間,讓優先順序更高的擁有更多的處理器的處理時間是非常合理的。
但是在另一些情況下可能表現就並非這麼理想了。
如果是兩個同等的低優先順序的程式,比如他們都是nice值為20的程式,那麼他們的時間片都為5ms,於是他們每執行5ms就會進行一次程式切換。如此就放大的程式切換所帶來的消耗,但是我們最初希望的是兩個程式都佔有CPU 50%的時間。在這樣的情況下,顯然無法實現。
CFS理想狀態
CFS全稱完全公平排程演算法。
在理想情況下,每個程式將能獲得1/n的處理器時間——n是指可執行程式的數量。
但是有很多因素使理想狀態無法實現:
1、一個處理器無法同時執行多個程式,程式切換本身有消耗,還會影響到快取的效率。
2、當時間片小到一定的程度,程式搶佔的代價會被放大。
CFS實現
在CFS中不再是nice值與時間片的絕對對映,而是讓nice值對應不同的權重,然後根據權重和實際執行時間來分配時間片。
比如有A、B兩個程式,他們對應的weight分別為1和3,週期時間為20ms,那麼A需要執行的時間就是1/4*20=5ms,B需要執行的時間就是3/4*20=15ms。
nice與weight的對應對如下:
static const int prio_to_weight[40] = {
/* -20 */ 88761, 71755, 56483, 46273, 36291,
/* -15 */ 29154, 23254, 18705, 14949, 11916,
/* -10 */ 9548, 7620, 6100, 4904, 3906,
/* -5 */ 3121, 2501, 1991, 1586, 1277,
/* 0 */ 1024, 820, 655, 526, 423,
/* 5 */ 335, 272, 215, 172, 137,
/* 10 */ 110, 87, 70, 56, 45,
/* 15 */ 36, 29, 23, 18, 15,
};
在這種情況下,執行的時間都是按照權值來計算,而不是之前的絕對時間,這樣就不會出現“時間片過小,放大程式切換所帶來的消耗”的問題了。
CFS下的程式選擇
主要思想:
CFS根據vruntime的值,將所有的程式存入紅黑樹,每次在紅黑樹中選擇vruntime最小的程式執行。同時CFS為了實現公平,必須懲罰正在執行的程式,以使那些正在等待的程式下次會被排程。(否則就會一直呼叫vruntime最小的程式到執行結束為止)
vruntime是虛擬執行時間,計算公式如下:(1024代表nice=0時的權重,上面表中有)
vruntime = 實際執行時間 * 1024 / 程式權重 (公式1)
由公式所得,如果一個程式執行的事件越長,那麼它的vruntime的值也會越大,被呼叫的概率也會越小。
因此,優先順序越高,已經執行時間越短的程式最會被呼叫。
另外這個公式還有一個演化:
vruntime = (排程週期 * 程式權重 / 所有程式總權重) * 1024 / 程式權重 = 排程週期 * 1024 / 所有程式總權重 (公式2)
從這個公式我們可以看到,雖然程式的權重不同,但是它們的 vruntime增長速度應該是一樣的 ,與權重無關。因此,通過vruntime 來選擇執行的程式,既能公平選擇程式,又能保證高優先順序程式獲得較多的執行時間。這就是CFS的主要思想了。
相關文章
- CFS排程引數: sched_wakeup_granularity
- linux程式排程Linux
- linux中設定程式排程的優先順序別Linux
- LInux實驗 : 程式排程模擬Linux
- 排程器簡介,以及Linux的排程策略Linux
- Kubernetes:CPU 配置、Linux CFS、程式語言的效能問題Linux
- Linux中什麼情況下會發生程式排程?Linux
- Linux程式排程邏輯與原始碼分析Linux原始碼
- Linux IO排程方法Linux
- Linux 中 Laravel 任務排程不執行LinuxLaravel
- Linux核心學習筆記(5)– 程式排程概述Linux筆記
- [譯] React 中的排程React
- linux搶佔式排程Linux
- Linux I/O排程器Linux
- 如何更改Linux的I/O排程器Linux
- Spark中資源排程和任務排程Spark
- Linux 定時任務排程Linux
- K8s中的排程程式是如何工作的? - danieleK8S
- Flink排程之排程器、排程策略、排程模式模式
- MySQL中的事件排程器EVENTMySql事件
- 程序中的執行緒排程執行緒
- Linux程序排程器-CPU負載Linux負載
- Linux Shell指令碼時間排程Linux指令碼
- 程式排程案例分析與常見疑惑1:為何不能排程?
- Android 中的定時任務排程Android
- 第 12 期 golang 中 goroutine 的排程Golang
- linux之 修改磁碟排程演算法Linux演算法
- Linux排程器:程序優先順序Linux
- 程式排程的原理和演算法探析演算法
- 軟中斷排程時機
- Pod的排程是由排程器(kube-scheduler)
- Go 併發程式設計 - runtime 協程排程(三)Go程式設計
- Yarn的排程器Yarn
- oracle排程程式作業dbms_schedulerOracle
- OS_程式排程:C++實現C++
- 詳解BI系統中的任務排程
- linux基礎(四)——任務排程cron和anacronLinux
- Linux之CPU排程策略和CPU親和性Linux
- 一文詳解 Linux Crontab 排程任務Linux