10 行代碼玩轉(zhuǎn)彈性調(diào)度的小把戲(彈性調(diào)班什么意思)
作者 | dog250
責(zé)編 | 唐小引
頭圖 | CSDN 下載自東方 IC
出品 | CSDN
Linux 的進(jìn)程調(diào)度器是通用的調(diào)度器,無(wú)論是 O(n)O(n),O(1)O(1),還是 CFS,均是基于統(tǒng)一的指標(biāo)來(lái)對(duì)待所有進(jìn)程的。也就是說(shuō),進(jìn)程甚至無(wú)法自主退讓。
只要確定了一個(gè)進(jìn)程的優(yōu)先級(jí),無(wú)論是是什么調(diào)度算法,該進(jìn)程的地位總是不會(huì)變化,如果能做到下面的策略就好了:
-
系統(tǒng)中進(jìn)程多了,就加速退讓。
系統(tǒng)中進(jìn)程少了,就加速搶占。
工人來(lái)了,就退讓。
經(jīng)理來(lái)了,就搶占。
……
考慮一個(gè)進(jìn)程 A 在一個(gè)特定的系統(tǒng)中運(yùn)行,它最多只能用 40%的 CPU,此時(shí),如果有另外的待運(yùn)行進(jìn)程,那么這些進(jìn)程自然分?jǐn)偭硗?60%的 CPU,如果再來(lái)一個(gè)進(jìn)程 A 呢?顯然,兩個(gè)進(jìn)程 A 的 CPU 時(shí)間均會(huì)減少。
能不能保證兩個(gè)進(jìn)程 A 仍然分別使用 40%的 CPU,然后其它進(jìn)程分?jǐn)偸S?20%的 CPU 呢?很難!
你可能說(shuō)可以配 group 啊,但是這必須有一個(gè)靜態(tài)的配置過(guò)程,很難動(dòng)態(tài)自適應(yīng)。
換句話說(shuō),Linux 的調(diào)度器是非彈性的!
下面的代碼展示了一個(gè)簡(jiǎn)單的彈性調(diào)度:
#!/usr/local/bin/stap -g
probe kernel.function("__enqueue_entity")
{
task = _task_of($se)
pid = @cast(task, "struct task_struct")->pid
if ($1 == pid) {
_nr = $cfs_rq->nr_running
t = $se->vruntime;
$se->vruntime = t 3000000*(_nr - 1)
}
}
意思是指定進(jìn)程根據(jù)系統(tǒng)中負(fù)載的數(shù)量來(lái)退讓?zhuān)?/p>
-
系統(tǒng)負(fù)載越高,指定進(jìn)程占有 CPU 時(shí)間比例越低。
系統(tǒng)負(fù)載越低,指定進(jìn)程占有 CPU 時(shí)間比例越高。
來(lái)來(lái)來(lái),看效果:
可以看到:
-
當(dāng)只有一個(gè) loop 的時(shí)候,它占用 100%的 CPU。
當(dāng)再生一個(gè) loop 的時(shí)候,它幾乎和第一個(gè) loop 平分 CPU。
當(dāng)越來(lái)越多的 loop 運(yùn)行的時(shí)候,第一個(gè) loop 的 CPU 份額逐漸降低。
本是同根生,只有第一個(gè) loop 被彈性了。
嗯,效果還行,但不夠平滑。試試二次曲線, or 三次曲線?
$se->vruntime = t 200*(_nr - 1)*_nr*_nr
// or
// $se->vruntime = t 20000*(_nr - 1)*_nr
200 何來(lái)?調(diào)一手好參數(shù)是必要的。
此外,我這里彈性策略過(guò)于單一,其實(shí)是可以設(shè)計(jì)的足夠復(fù)雜的,比如針對(duì)特定進(jìn)程的特定策略,即便是簡(jiǎn)單的雙斜率直線段,也比我這個(gè) OK,是吧,不多說(shuō)。
有人問(wèn),如何找到要修改的代碼在哪里,只要對(duì) Linux 內(nèi)核的執(zhí)行原理足夠熟悉,這并不難,對(duì)于手藝人而言,阿基米德,魯班,庖丁,黃道婆這些人的地位是堪比歐幾里得,笛卡爾的。
原文鏈接:https://blog.csdn.net/dog250/article/details/108281228
點(diǎn)分享