一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

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

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

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

Linux如何讓某一個線程排他性獨占CPU

Linux閱碼場 ? 來源:Linux閱碼場 ? 2023-11-05 09:39 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

內(nèi)容簡介

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

工程需求

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

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

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

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

taskset-c 2 pn_dev

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

Part 2

用戶態(tài)隔離

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

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

811d5ff8-7b25-11ee-939d-92fbcf53809c.png

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

812f096a-7b25-11ee-939d-92fbcf53809c.png

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

8141927e-7b25-11ee-939d-92fbcf53809c.png

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

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

81507460-7b25-11ee-939d-92fbcf53809c.png

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

81742b44-7b25-11ee-939d-92fbcf53809c.png

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

Part 3

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

中斷

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

對于中斷,我們特別容易查看,就是實際去驗證每個IRQ的smp_affinity就好了:

8194be18-7b25-11ee-939d-92fbcf53809c.png

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

echo 2 >/proc/irq/44/smp_affinity_list

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

81a6e624-7b25-11ee-939d-92fbcf53809c.png

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

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

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

81b95a66-7b25-11ee-939d-92fbcf53809c.png

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

81e4ffb8-7b25-11ee-939d-92fbcf53809c.png

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

81fc3b4c-7b25-11ee-939d-92fbcf53809c.png

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

8223faa6-7b25-11ee-939d-92fbcf53809c.png

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

82404576-7b25-11ee-939d-92fbcf53809c.png

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

82644142-7b25-11ee-939d-92fbcf53809c.png

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

827d824c-7b25-11ee-939d-92fbcf53809c.png

發(fā)現(xiàn)CPU2上面的tick穩(wěn)定在188上面,這樣相信你會更加開心,因為你獨占地更加徹底了!

下面,我們再放一個task進(jìn)去CPU2,有2個任務(wù)的情況下,CPU2上面的timer tick開始增加:

82945e9a-7b25-11ee-939d-92fbcf53809c.png

不過,這或許不是個問題,因為我們說好了“獨占”,1個任務(wù)獨占的時候,timer tick不來打擾,應(yīng)該已經(jīng)是非常理想的情況了!

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

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

./dma_map_benchmark -s 120 -t 16

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

82b5de80-7b25-11ee-939d-92fbcf53809c.png

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

82c8a650-7b25-11ee-939d-92fbcf53809c.png

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

Part 4

最佳實踐指南

對于實時性要求高、高性能計算等場景,如果要讓某個任務(wù)獨占CPU,最理想的選擇是:

1.采用isolcpus隔離CPU

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

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

4.使能NO_HZ_FULL,則效果更佳,因為連timer tick中斷也不打擾你了。

審核編輯:湯梓紅

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

    關(guān)注

    68

    文章

    11080

    瀏覽量

    217099
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11511

    瀏覽量

    213823
  • 程序
    +關(guān)注

    關(guān)注

    117

    文章

    3826

    瀏覽量

    82993
  • 線程
    +關(guān)注

    關(guān)注

    0

    文章

    508

    瀏覽量

    20216

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

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

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    單核CPU為何也支持多線程

    線程上下文是指某一時間點 CPU 寄存器和程序計數(shù)器的內(nèi)容,CPU通過時間片分配算法來循環(huán)執(zhí)行任務(wù)(線程),因為時間片非常短,所以
    發(fā)表于 09-16 11:05 ?3080次閱讀

    我想壓力達(dá)到某一個數(shù)值的時候,再讓plc的輸入端產(chǎn)生...

    請教各位大神下,我想壓力達(dá)到某一個數(shù)值的時候,再讓plc的輸入端產(chǎn)生高電平。我該用哪種傳感器呢?謝謝!
    發(fā)表于 11-24 17:28

    如何將二維數(shù)組里面大于或小于某一個數(shù)值的數(shù)值替換

    大神們問下如何將二維數(shù)組里面大于或小于某一個數(shù)值的數(shù)值替換成其他的數(shù)(或者是把數(shù)組里面的數(shù)同時減去某一個數(shù))
    發(fā)表于 05-24 14:54

    Labview讀取excel信息時怎么查詢檢索某一個用戶的全部信息?

    Labview讀取excel信息時怎么查詢檢索某一個用戶的全部信息?
    發(fā)表于 04-20 16:11

    請問怎么設(shè)置某一個元器件的鋪銅規(guī)則?

    如何設(shè)置某一個元器件的鋪銅規(guī)則?
    發(fā)表于 05-08 07:35

    請問定時器的TRGO事件會輸出到某一個IO引腳嗎?

    1、 定時器的TRGO事件會輸出到某一個IO引腳嗎?2、用定時器的TRGO事件觸發(fā)DAC又是什么意思?硬件上還要怎么連接?
    發(fā)表于 10-15 23:20

    一個簡單跟蹤線程cpu消耗的介紹

    當(dāng)遇到線程線程間搶占資源的時候我們無從下手,不知道是怎么回事。本文做一個簡單跟蹤線程cpu消耗的介紹。二、方法:①首先我們要去抓取每個
    發(fā)表于 12-15 08:40

    BuildRoot什么時候需要全部重新編譯某一個

    BuildRoot如何增加包呢?BuildRoot如何單獨編譯某一個包?BuildRoot什么時候需要全部重新編譯,什么時候只需要單獨編譯某一個包?
    發(fā)表于 02-21 06:38

    線程編程之Linux線程編程

    9.2 Linux線程編程 9.2.1 線程基本編程 這里要講的線程相關(guān)操作都是用戶空間中的線程的操作。在
    發(fā)表于 10-18 15:55 ?3次下載

    Linux下查看某一個程序所使用的內(nèi)存方法

    Linux款免費(fèi)的操作系統(tǒng),用戶可以通過網(wǎng)絡(luò)或其他途徑免費(fèi)獲得,并可以任意修改其源代碼。這是其他的操作系統(tǒng)所做不到的。正是由于這點,來自全世界的無數(shù)程序員參與了Linux的修改、
    發(fā)表于 12-01 16:18 ?4670次閱讀
    <b class='flag-5'>Linux</b>下查看<b class='flag-5'>某一個</b>程序所使用的內(nèi)存方法

    Linux下的多線程編程

    進(jìn)程(process)中只允許有線程,這樣多線程就意味著多進(jìn)程。現(xiàn)在,多線程技術(shù)已經(jīng)被許多操作系統(tǒng)所支持,包括Windows/NT,當(dāng)然
    發(fā)表于 04-02 14:43 ?718次閱讀

    如何對OrCAD原理圖中某一個元件進(jìn)行批量替換

    有時要對原理圖中某一個元件批量替換,或者給同種元件統(tǒng)添加屬性值,這就要用到replace cache和update cache命令。
    發(fā)表于 11-27 15:44 ?1.1w次閱讀
    如何對OrCAD原理圖中<b class='flag-5'>某一個</b>元件進(jìn)行批量替換

    虛擬機(jī):查看linux線程CPU占用率的方法

    虛擬機(jī):查看linux線程CPU占用率的方法
    的頭像 發(fā)表于 06-22 10:06 ?4346次閱讀
    虛擬機(jī):查看<b class='flag-5'>linux</b><b class='flag-5'>線程</b>的<b class='flag-5'>CPU</b>占用率的方法

    Linux實時任務(wù)獨占CPU的事

    本文主要討論在高實時要求、高效能計算、DPDK等領(lǐng)域,Linux如何某一個線程排他性獨占
    的頭像 發(fā)表于 02-20 17:11 ?3462次閱讀
    談<b class='flag-5'>一</b>談<b class='flag-5'>Linux</b><b class='flag-5'>讓</b>實時任務(wù)<b class='flag-5'>獨占</b><b class='flag-5'>CPU</b>的事

    嵌入式Linux線程CPU消耗查看

    的辦法來實現(xiàn)這些功能。第步在Linux環(huán)境下的線程其實就是輕量級的進(jìn)程,但是我們通過top 或 ps -aux 命令般都是查不到具體的線程
    發(fā)表于 11-01 16:32 ?10次下載
    嵌入式<b class='flag-5'>Linux</b>下<b class='flag-5'>線程</b><b class='flag-5'>CPU</b>消耗查看