0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

談一談Linux讓實(shí)時(shí)任務(wù)獨(dú)占CPU的事

Linux閱碼場(chǎng) ? 來(lái)源:Linuxer ? 作者:Linuxer ? 2021-02-20 17:11 ? 次閱讀

本文主要討論在高實(shí)時(shí)要求、高效能計(jì)算、DPDK等領(lǐng)域,Linux如何讓某一個(gè)線程排他性獨(dú)占CPU;獨(dú)占CPU涉及的線程、中斷隔離原理;以及如何在排他性獨(dú)占的情況下,甚至讓系統(tǒng)的timer tick也不打斷獨(dú)占任務(wù),從而實(shí)現(xiàn)最低的延遲抖動(dòng)。

本文目錄:

1. 工程需求

2. 用戶態(tài)隔離

3. 內(nèi)核態(tài)隔離

3.1 中斷

3.2 內(nèi)核線程

4. 最佳實(shí)踐指南

Part 1

工程需求

在一個(gè)SMP或者NUMA系統(tǒng)中,CPU的數(shù)量大于1。在工程中,我們有時(shí)候有一種需求,就是讓某個(gè)能夠獨(dú)占CPU,這個(gè)CPU什么都不做,就只做指定的任務(wù),從而獲得低延遲、高實(shí)時(shí)的好處。

比如在DPDK中,通過(guò)設(shè)置

GRUB_CMDLINE_LINUX_DEFAULT=“isolcpus=0-3,5,7”

隔離CPU0,3,5,7,讓DPDK的任務(wù)在運(yùn)行的時(shí)候,其他任務(wù)不會(huì)和DPDK的任務(wù)進(jìn)行上下文切換,從而保證網(wǎng)絡(luò)性能最佳[1]。在Realtime應(yīng)用場(chǎng)景中,通過(guò)isolcpus=2隔離CPU2,然后把實(shí)時(shí)應(yīng)用通過(guò)taskset綁定到隔離的核:

taskset-c 2 pn_dev

從而保證低延遲要求[2]。

Part 2

用戶態(tài)隔離

這個(gè)地方,我們可以看出,它們統(tǒng)一都使用了isolcpus這樣一個(gè)啟動(dòng)參數(shù)

實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn),下面我們來(lái)啟動(dòng)一個(gè)8核的ARM64系統(tǒng),運(yùn)行Ubuntu,并指定isolcpus=2這個(gè)啟動(dòng)參數(shù):

3724778a-71ad-11eb-8b86-12bb97331649.png

系統(tǒng)啟動(dòng)后,我們運(yùn)行下面簡(jiǎn)單的程序(啟動(dòng)8個(gè)進(jìn)程運(yùn)行while死循環(huán)):

375f64ee-71ad-11eb-8b86-12bb97331649.png

我們是8核的,現(xiàn)在又是運(yùn)行8個(gè)進(jìn)程,所以理論上來(lái)講,負(fù)載均衡后,8個(gè)進(jìn)程應(yīng)該均分地運(yùn)行在8個(gè)核上面,但是我們來(lái)看看實(shí)際的htop結(jié)果:

37807ec2-71ad-11eb-8b86-12bb97331649.png

我們發(fā)現(xiàn)3(也就是CPU2)上面的CPU占用率是0.0%。這實(shí)證了CPU2已經(jīng)被隔離,用戶空間的進(jìn)程不能在它上面跑。

當(dāng)然,這個(gè)時(shí)候,我們可以通過(guò)taskset,強(qiáng)行把其中的一個(gè)a.out,綁定到CPU2上面去:

37cd7dd0-71ad-11eb-8b86-12bb97331649.png

從上面命令的結(jié)果看出,663原本的affinity list只有0,1,3-7是沒(méi)有2的,而我們強(qiáng)行把它設(shè)置為了2,之后再看htop,CPU2上面占用100%:

380fa0f2-71ad-11eb-8b86-12bb97331649.png

通過(guò)上面的實(shí)驗(yàn),我們明顯可以看出isolcpus=2使得CPU2上無(wú)法再運(yùn)行用戶空間的進(jìn)程了(除非手動(dòng)設(shè)置affinity)。

Part 3

內(nèi)核態(tài)隔離

中斷

但是,能在CPU2上面運(yùn)行的,不是只有用戶態(tài)的任務(wù),還可以有內(nèi)核線程、中斷等,那么isolcpus=能否隔離內(nèi)核線程和中斷呢?

對(duì)于中斷,我們特別容易查看,就是實(shí)際去驗(yàn)證每個(gè)IRQ的smp_affinity就好了:

3841b6c8-71ad-11eb-8b86-12bb97331649.png

從上圖明顯可以看出,對(duì)于44、47號(hào)這種外設(shè)的中斷,Linux內(nèi)核把smp_affinity設(shè)置為了FB(11111011),明顯避開(kāi)了CPU2,所以,實(shí)際外設(shè)中斷也不會(huì)在CPU2發(fā)生,除非我們強(qiáng)行給中斷綁核,比如讓44號(hào)中斷綁定到CPU2:

echo 2 》/proc/irq/44/smp_affinity_list

之后,我們發(fā)現(xiàn)44號(hào)中斷在CPU2可以發(fā)生:

386bdfca-71ad-11eb-8b86-12bb97331649.png

但是,系統(tǒng)的timer中斷、IPI,由于是Linux系統(tǒng)的運(yùn)行基石,實(shí)際還是要在CPU2上面運(yùn)行的。這里面最可能給任務(wù)帶來(lái)延遲抖動(dòng)的,自然是timer tick。

下面我們重點(diǎn)探討下tick的問(wèn)題,由于Linux一般情況下,已經(jīng)配置IDLE狀態(tài)的NO_HZ tickless,所以CPU2上面什么都不跑的時(shí)候,實(shí)際timer中斷幾乎不發(fā)生。

下面,我們還是在isolcpus=2的情況下,運(yùn)行前面那個(gè)8個(gè)進(jìn)程的a.out,默認(rèn)情況下沒(méi)有任務(wù)會(huì)占用CPU2。通過(guò)先后運(yùn)行幾次cat /proc/interrupts | head 2,我們會(huì)看到其他core的timer中斷頻繁發(fā)生,而CPU2幾乎不變,這顯然是IDLE時(shí)候的NO_HZ在發(fā)揮省電的作用:

388fdf92-71ad-11eb-8b86-12bb97331649.png

但是,一旦我們放任務(wù)到CPU2,哪怕只是放1個(gè),就會(huì)發(fā)現(xiàn)CPU2上面的timer中斷開(kāi)始增加:

38b28a6a-71ad-11eb-8b86-12bb97331649.png

這說(shuō)明一點(diǎn),哪怕隔離的CPU上面只有一個(gè)線程去跑,timer tick就會(huì)開(kāi)始跑,當(dāng)然,這個(gè)timer tick也會(huì)頻繁打斷這一個(gè)線程,從而造成大量的上下文切換。你肯定會(huì)覺(jué)得Linux怎么這么傻,既然只有一個(gè)人,那也沒(méi)有時(shí)間片分片的必要,不需要在2個(gè)或者多個(gè)任務(wù)進(jìn)行時(shí)間片劃分地調(diào)度,為啥還要跑tick?其實(shí)原因是我們的內(nèi)核默認(rèn)只是使能了IDLE的NO_HZ:

390e92c4-71ad-11eb-8b86-12bb97331649.png

我們來(lái)重新編譯一個(gè)內(nèi)核,使能NO_HZ_FULL:

39338926-71ad-11eb-8b86-12bb97331649.png

當(dāng)我們使能了NO_HZ_FULL后,Linux支持在CPU上僅有1個(gè)任務(wù)的時(shí)候,是可以NO_HZ的。但是有2個(gè)就傻眼了,所以這個(gè)“FULL”也不是真地FULL[3]。這當(dāng)然也可以理解,因?yàn)橛?個(gè)就涉及到時(shí)間片調(diào)度的問(wèn)題。什么時(shí)候應(yīng)該使能NO_HZ_FULL,內(nèi)核文檔Documentation/timers/no_hz.rst有明確地“指示”,只有在實(shí)時(shí)和HPC等的場(chǎng)景,才需要,否則默認(rèn)的NO_HZ_IDLE是你最好的選擇:

3959e594-71ad-11eb-8b86-12bb97331649.png

我們重新編譯了內(nèi)核,選中了NO_HZ_FULL,下面啟動(dòng)Linux,注意啟動(dòng)的時(shí)候參數(shù)添加nohz_full=2,讓CPU2支持NO_HZ_FULL:

3a7d168a-71ad-11eb-8b86-12bb97331649.png

重新運(yùn)行CPU2只有一個(gè)任務(wù)的場(chǎng)景,看看它的timer中斷發(fā)生情況:

3abb29a2-71ad-11eb-8b86-12bb97331649.png

發(fā)現(xiàn)CPU2上面的tick穩(wěn)定在188上面,這樣相信你會(huì)更加開(kāi)心,因?yàn)槟悛?dú)占地更加徹底了!

下面,我們?cè)俜乓粋€(gè)task進(jìn)去CPU2,有2個(gè)任務(wù)的情況下,CPU2上面的timer tick開(kāi)始增加:

3aed457c-71ad-11eb-8b86-12bb97331649.png

不過(guò),這或許不是個(gè)問(wèn)題,因?yàn)槲覀冋f(shuō)好了“獨(dú)占”,1個(gè)任務(wù)獨(dú)占的時(shí)候,timer tick不來(lái)打擾,應(yīng)該已經(jīng)是非常理想的情況了!

內(nèi)核態(tài)線程

內(nèi)核態(tài)的線程其實(shí)和用戶態(tài)差不多,當(dāng)它們沒(méi)有綁定到隔離的CPU的時(shí)候,是不會(huì)跑到隔離CPU運(yùn)行的。下面用筆者在內(nèi)核里面添加的dma_map_benchmark來(lái)做實(shí)驗(yàn)[4],開(kāi)啟16個(gè)內(nèi)核線程來(lái)進(jìn)行DMA map和unmap(注意我們只有8個(gè)核):

。/dma_map_benchmark -s 120 -t 16

我們看到CPU2上面的CPU占用也是0:

3b193696-71ad-11eb-8b86-12bb97331649.png

內(nèi)核里面的dma_map_benchmark線程在狂占CPU0-1, 3-7,但是就是不去占CPU2:

3b3b2788-71ad-11eb-8b86-12bb97331649.png

但是,內(nèi)核線程如果用kthread_bind_mask()類(lèi)似API把線程綁定到了隔離的CPU,則情況就不一樣了,這就類(lèi)似用taskset把用戶態(tài)的任務(wù)綁定到CPU一樣。

Part 4

最佳實(shí)踐指南

對(duì)于實(shí)時(shí)性要求高、高性能計(jì)算等場(chǎng)景,如果要讓某個(gè)任務(wù)獨(dú)占CPU,最理想的選擇是:

1. 采用isolcpus隔離CPU

2. 將指定任務(wù)綁定到隔離CPU

3. 小心意外地把中斷、內(nèi)核線程綁定到了隔離CPU,排查到這些“意外”分子

4. 使能NO_HZ_FULL,則效果更佳,因?yàn)檫Btimer tick中斷也不打擾你了。

原文標(biāo)題:宋寶華:談一談Linux讓實(shí)時(shí)/高性能任務(wù)獨(dú)占CPU的事

文章出處:【微信公眾號(hào):Linuxer】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    10890

    瀏覽量

    212430
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11329

    瀏覽量

    209975

原文標(biāo)題:宋寶華:談一談Linux讓實(shí)時(shí)/高性能任務(wù)獨(dú)占CPU的事

文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場(chǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    望獲實(shí)時(shí)Linux系統(tǒng)與Betaflight的結(jié)合:計(jì)算與飛控的完美協(xié)作

    Linux系統(tǒng)實(shí)現(xiàn)高級(jí)計(jì)算任務(wù),同時(shí)通過(guò)Betaflight實(shí)現(xiàn)無(wú)人機(jī)的飛控功能。 、望獲實(shí)時(shí)Linux與Betaflight的角色分工
    的頭像 發(fā)表于 01-10 16:17 ?96次閱讀

    LinuxCPU調(diào)度策略和CPU親和性

    、調(diào)度策略 調(diào)度進(jìn)程 單個(gè) CPU次只能執(zhí)行個(gè)進(jìn)程,雖然 Linux 系統(tǒng)通過(guò)使用多任務(wù)
    的頭像 發(fā)表于 12-05 16:38 ?537次閱讀
    <b class='flag-5'>Linux</b>之<b class='flag-5'>CPU</b>調(diào)度策略和<b class='flag-5'>CPU</b>親和性

    Linux計(jì)劃任務(wù)介紹

    1.計(jì)劃任務(wù)(定時(shí)任務(wù))基本概述 1.什么是crond crond就是計(jì)劃任務(wù),類(lèi)似于我們平時(shí)生活中的鬧鐘。定點(diǎn)執(zhí)行。 2.為什么要使用crond?crond主要是做些周期性的
    的頭像 發(fā)表于 11-24 15:49 ?319次閱讀

    定時(shí)器技術(shù):Air780E如何革新定時(shí)任務(wù)管理?

    今天講的是關(guān)于Air780E如何革新定時(shí)任務(wù)管理的內(nèi)容,希望大家有所收獲。
    的頭像 發(fā)表于 11-07 13:50 ?278次閱讀
    定時(shí)器技術(shù):Air780E如何革新定<b class='flag-5'>時(shí)任務(wù)</b>管理?

    混合部署 | 在迅為RK3568上同時(shí)部署RT-Thread和Linux系統(tǒng)

    RT-Thread介紹 RT-Thread 是個(gè)高安全性、實(shí)時(shí)性的操作系統(tǒng),廣泛應(yīng)用于任務(wù)關(guān)鍵領(lǐng)域,例如電力、軌道交通、車(chē)載系統(tǒng)、工業(yè)控制和新能源等。它的加入 RK3568 能夠在
    發(fā)表于 11-01 10:31

    混合部署 | 在迅為RK3568上同時(shí)部署RT-Thread和Linux系統(tǒng)

    RT-Thread介紹 RT-Thread 是個(gè)高安全性、實(shí)時(shí)性的操作系統(tǒng),廣泛應(yīng)用于任務(wù)關(guān)鍵領(lǐng)域,例如電力、軌道交通、車(chē)載系統(tǒng)、工業(yè)控制和新能源等。它的加入 RK3568 能夠在
    發(fā)表于 09-18 10:54

    freertos最多支持多少個(gè)任務(wù)

    FreeRTOS是個(gè)輕量級(jí)的實(shí)時(shí)操作系統(tǒng)(RTOS),其設(shè)計(jì)初衷就是為了提供簡(jiǎn)單、可靠且高效的實(shí)時(shí)任務(wù)管理。關(guān)于FreeRTOS最多支持多少個(gè)任務(wù)的問(wèn)題,實(shí)際上并沒(méi)有
    的頭像 發(fā)表于 09-02 14:21 ?1082次閱讀

    linux時(shí)任務(wù)的用法總結(jié)

    習(xí)慣了使用 windows 的計(jì)劃任務(wù),使用 linux 中的 crontab 管理定時(shí)任務(wù)時(shí)很不適應(yīng)。
    的頭像 發(fā)表于 08-14 18:16 ?881次閱讀
    <b class='flag-5'>linux</b>定<b class='flag-5'>時(shí)任務(wù)</b>的用法總結(jié)

    實(shí)時(shí)Linux:解鎖高效能和可靠性的關(guān)鍵

    實(shí)時(shí)Linux結(jié)合容器技術(shù),提供了高度靈活和可擴(kuò)展的解決方案,特別適合于需要快速響應(yīng)和高可靠性的應(yīng)用場(chǎng)景。實(shí)時(shí)Linux能夠保證關(guān)鍵任務(wù)及時(shí)
    的頭像 發(fā)表于 08-08 11:21 ?312次閱讀
    <b class='flag-5'>實(shí)時(shí)</b><b class='flag-5'>Linux</b>:解鎖高效能和可靠性的關(guān)鍵

    談一談FPGA設(shè)計(jì)中的功率計(jì)算

    散熱問(wèn)題,如對(duì)系統(tǒng)增加散熱片或氣流,從而有效地降低運(yùn)行溫度。那么,在系統(tǒng)建立之前,設(shè)計(jì)師怎樣才能夠準(zhǔn)確地估計(jì)功耗和設(shè)備的熱耗?這相當(dāng)于在談?wù)?b class='flag-5'>一個(gè)先有雞還是先有蛋的問(wèn)題!幸運(yùn)的是,有個(gè)專(zhuān)為這項(xiàng)任務(wù)而設(shè)計(jì)的功耗
    發(fā)表于 07-31 22:37

    ESP8266如何實(shí)現(xiàn)時(shí)間小于3us的定時(shí)任務(wù)?

    想實(shí)現(xiàn)個(gè)穩(wěn)定的軟串口,現(xiàn)有的軟串口程序是通過(guò)中斷實(shí)現(xiàn)的,但中斷好像會(huì)被其他中斷打斷,導(dǎo)致數(shù)據(jù)丟失,定時(shí)器按文檔上的說(shuō)法,只能大于50us,能不能實(shí)現(xiàn)時(shí)間小于3us的定時(shí)任務(wù)或者提高GPIO中斷的優(yōu)先級(jí)呢?或者還有其他什么辦法?
    發(fā)表于 07-19 06:13

    使用 PREEMPT_RT 在 Ubuntu 中構(gòu)建實(shí)時(shí) Linux 內(nèi)核

    實(shí)時(shí)內(nèi)核補(bǔ)丁來(lái)完成。簡(jiǎn)介我們?cè)榻B過(guò)在Ubuntu22.04中啟用實(shí)時(shí)Linux內(nèi)核有多簡(jiǎn)單,因?yàn)镃anonical已將該內(nèi)核列為個(gè)選項(xiàng)。但要為默認(rèn)
    的頭像 發(fā)表于 04-12 08:36 ?2652次閱讀
    使用 PREEMPT_RT 在 Ubuntu 中構(gòu)建<b class='flag-5'>實(shí)時(shí)</b> <b class='flag-5'>Linux</b> 內(nèi)核

    DMA在嵌入式實(shí)時(shí)任務(wù)處理中的應(yīng)用

    DMA:Direct Memory Access,直接內(nèi)存存取/訪問(wèn)。簡(jiǎn)單來(lái)說(shuō)就是內(nèi)存RAM直接和其他設(shè)備(外設(shè))進(jìn)行數(shù)據(jù)交互,而不需要CPU參與的種控制器。
    發(fā)表于 04-05 10:05 ?739次閱讀

    HarmonyOS CPU與I/O密集型任務(wù)開(kāi)發(fā)指導(dǎo)

    、CPU密集型任務(wù)開(kāi)發(fā)指導(dǎo) CPU密集型任務(wù)是指需要占用系統(tǒng)資源處理大量計(jì)算能力的任務(wù),需要長(zhǎng)
    的頭像 發(fā)表于 02-18 10:17 ?990次閱讀
    HarmonyOS <b class='flag-5'>CPU</b>與I/O密集型<b class='flag-5'>任務(wù)</b>開(kāi)發(fā)指導(dǎo)

    使用TC21x的GPT實(shí)現(xiàn)1m計(jì)時(shí)器執(zhí)行定時(shí)任務(wù),怎么配置GTM和GPT?

    專(zhuān)家們好,我想使用TC21x的GPT實(shí)現(xiàn)1m計(jì)時(shí)器執(zhí)行定時(shí)任務(wù),不知道怎么配置GTM和GPT?
    發(fā)表于 02-06 06:47