代碼邏輯比較簡單:
1、確定就緒隊列的當前執(zhí)行的調(diào)度實體
/* 確定就緒隊列的當前執(zhí)行進程curr */
struct sched_entity *curr = cfs_rq- >curr;
2、根據(jù)獲取的當前執(zhí)行進程,計算當前和上一次更新負荷權(quán)重時兩次的時間的差值
u64 now = rq_clock_task(rq_of(cfs_rq));
u64 delta_exec;
if (unlikely(!curr))
return;
delta_exec = now - curr- >exec_start;
if (unlikely((s64)delta_exec <= 0))
return;
3、重新更新啟動時間exec_start為now,以備下次計算時使用,最后將計算出的時間差加到先前的統(tǒng)計時間上。
/* 重新更新啟動時間exec_start為now */
curr- >exec_start = now;
schedstat_set(curr- >statistics.exec_max,
max(delta_exec, curr- >statistics.exec_max));
/* 將時間差加到先前統(tǒng)計的時間即可 */
curr- >sum_exec_runtime += delta_exec;
schedstat_add(cfs_rq, exec_clock, delta_exec);
這也是通過cat /proc/$pid/sched看到的一些統(tǒng)計信息
4、開始計算虛擬時間
curr- >vruntime += calc_delta_fair(delta_exec, curr);
5、計算虛擬時間函數(shù)calc_delta_fair如下,忽略舍入和溢出檢查,calc_delta_fair函數(shù)所做的計算如下:
/*
* delta /= w
*/
static inline u64 calc_delta_fair(u64 delta, struct sched_entity *se)
{
if (unlikely(se- >load.weight != NICE_0_LOAD))
delta = __calc_delta(delta, NICE_0_LOAD, &se- >load);
return delta;
}
其中NICE_0_LOAD的值為:1024,當進程的nice=0時,不需要進行加權(quán)處理,其虛擬時間就等于其實際運行時間。
# define SCHED_FIXEDPOINT_SHIFT 10
#define NICE_0_LOAD_SHIFT (SCHED_FIXEDPOINT_SHIFT)
#define NICE_0_LOAD (1L < < NICE_0_LOAD_SHIFT)
?1024也就是Nice值為0對應(yīng)的權(quán)重值,權(quán)重值在內(nèi)核中是預(yù)先定義好的,如下所示:
const int sched_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,
};
通過公式和內(nèi)核預(yù)先設(shè)定的權(quán)重表,可以看出來:
Nice值越高(對應(yīng)的優(yōu)先級越低),權(quán)重越小,虛擬時間累加的越快(虛擬時間過得越快),Nice值越低(對應(yīng)的優(yōu)先級越高),權(quán)值越高,虛擬時間累加的越慢(虛擬時間過得越慢)。CFS的思想核心也就是這樣,讓每個調(diào)度實體的虛擬時間增加速度不同,使用虛擬時間來衡量調(diào)度實體在CPU上已經(jīng)執(zhí)行的時間。
總結(jié):
不同優(yōu)先級的進程以各自對應(yīng)的速度推進虛擬時間,只要保證在一個調(diào)度延遲內(nèi)虛擬時間的推進進展相同,就實現(xiàn)了完成公平,公平指的是相對公平,即按進程的權(quán)重給予不同的運行時間,虛擬時間越小,代表著受到了"不公平"對待,因此下一個參與調(diào)度的調(diào)度實體就是紅黑樹中的最左邊(虛擬時間最小)的節(jié)點,如此一來既能公平選擇進程,又能保證高權(quán)重進程獲得較多的運行時間。
-
Linux
+關(guān)注
關(guān)注
87文章
11345瀏覽量
210395 -
代碼
+關(guān)注
關(guān)注
30文章
4827瀏覽量
69052
發(fā)布評論請先 登錄
相關(guān)推薦
如何縮短Vivado的運行時間
![如何縮短Vivado的<b class='flag-5'>運行時間</b>](https://file.elecfans.com/web1/M00/94/F1/pIYBAFzuKWmACRntAAAPzPfTtK4564.png)
如何檢查Linux服務(wù)器的運行時間
![如何檢查Linux服務(wù)器的<b class='flag-5'>運行時間</b>](https://file.elecfans.com/web2/M00/7D/AF/poYBAGOAbC2AFa3XAABWLqOp3eI136.png)
stm32cubeIDE代碼運行時間如何查看?
請問6747如何測量代碼運行時間?
如何用SysTick實現(xiàn)測量程序運行時間
![如何用SysTick實現(xiàn)測量程序<b class='flag-5'>運行時間</b>](https://file.elecfans.com/web1/M00/50/62/pIYBAFrykXeAQcU0AAMDRBP-0o0211.png)
如何高效測量ECU的運行時間
淺析STM32代碼運行時間的技巧
![淺析STM32<b class='flag-5'>代碼</b><b class='flag-5'>運行時間</b>的技巧](https://file.elecfans.com/web2/M00/1C/03/pYYBAGGJ1TqAPAOcAAAl1aur50g531.png)
Linux虛擬運行時間的計算
![Linux<b class='flag-5'>虛擬</b><b class='flag-5'>運行時間</b>的<b class='flag-5'>計算</b>](https://file1.elecfans.com/web2/M00/8E/71/wKgaomTHJm2AFIq5AAALtqcNz-A471.jpg)
評論