本文來自微信公眾號:編程技術(shù)宇宙 (ID:xuanyuancoding),作者:軒轅之風(fēng) O
中斷機(jī)制
我是 CPU 一號車間的阿 Q,我又來了!
我們?nèi)粘5墓ぷ骶褪遣粩鄨?zhí)行代碼指令,不過這看似簡單的工作背后其實也并不輕松。
咱不能悶著頭啥也不管一個勁的只管執(zhí)行代碼,還得和連接在主板上的其他單位打交道。經(jīng)常保持聯(lián)系的有鍵盤、鼠標(biāo)、磁盤,哦對,還有網(wǎng)卡,這家伙最近把我惹到了,待會再說這事兒。
原以為內(nèi)存那家伙已經(jīng)夠慢的了,沒想到跟上面這幾位通個信比他更慢,咱 CPU 工廠的時間一刻值千金,不能干等著,耽誤工夫。后來廠里一合計,想了個叫中斷的辦法。
在我們車間裝了個大燈,這些單位想聯(lián)系我們辦事兒,就先給我們發(fā)一個中斷信號,大燈就會自動亮起。我們平時工作執(zhí)行代碼指令的時候,每執(zhí)行一條指令就會瞅一眼看看大燈有沒有亮起來。一旦發(fā)現(xiàn)燈亮了,就把手頭的工作先放一邊,去處理一下。
我們記性很差的,等會處理了完了還得回來接著原來的活繼續(xù)干,為了等會回來還能接的起來,走之前得把當(dāng)前執(zhí)行的這個線程的各個寄存器的值,執(zhí)行到哪里了等等這些信息都保存在這個線程的棧里去。
不過有時候我們在執(zhí)行非常重要的事情的時候,就不想被他們打斷。于是我們又在車間里那個 eflags 寄存器中設(shè)置了一個標(biāo)記,如果是 1 我們才允許被打斷,如果是 0 那就算天王老子找我們也不管了。
哦不對,還有一種不可以屏蔽的中斷 NMI,走得是綠色通道。不過我可不期望有這種事情發(fā)生,因為一般都沒有好事,不是電源斷電就是溫度過高,或者總線出了錯誤等這之類嚴(yán)重的事情。
8259A PIC
還有一個問題,找我們辦事兒的單位有很多,我們得要區(qū)分開來,到底是誰來消息了,而且要是他們一起來找,按什么樣優(yōu)先級順序處理,也是一件頭疼的事情。
為此,廠里單獨組建了一個全資的子公司來負(fù)責(zé)這事兒,他就是可編程中斷控制器 PIC,外號 8259A,其他單位想聯(lián)系我們都得通過這個 PIC,我們只需要和 PIC 進(jìn)行對接就可以了。
我們給辦事單位都分配了一個編號,叫做中斷向量。我們還準(zhǔn)備了一個表格叫中斷描述符表 IDT,表格里記錄了很多信息,其中就有處理這個中斷號對應(yīng)的函數(shù)地址。我們找 PIC 拿到編號后就執(zhí)行處理函數(shù)就 OK 了。
這個表格有點大,足足有 256 項,咱 CPU 車間空間有限,放不下,就把它放在內(nèi)存那家伙那里了,為了能快速找到這個表,專門添置了一個叫 idtr 的寄存器指向這個表格。
其實除了中斷,我們在執(zhí)行指令的時候如果遇到了異常情況,也會去這個表里執(zhí)行異常處理函數(shù),最常見的比如遇到了除數(shù)是 0,內(nèi)存地址錯誤等等情況。
這種情況下,我們必須主動放下手里的活,去處理異常,所以我們也說異常是同步的,而中斷不知道什么時候發(fā)生,所以是異步的。
APIC
8259A 干的挺不錯的,不過后來咱們廠擴(kuò)大規(guī)模,從單核 CPU 變成了多核,他就有點應(yīng)付不過來了。
終于有一天,廠里召開會議,把 8259A 給撤了,成立了一個新的全資子公司叫高級可編程中斷控制器 APIC,名字就多了個高級兩個字,干的活還是一樣的。
不過你還別說,這兩個字還真不是吹噓,比 8259A 不知道高到哪里去了。
這個 APIC 的新公司一上臺,就成立了兩個部門,一個叫 I / O APIC,負(fù)責(zé)接待那些要找我們辦事兒的單位,一個叫 Local APIC,以外包的形式入駐到我 CPU 的各個車間工作,因為就挨著我們辦公,所以取名叫 Local。
I / O APIC 收到中斷信號以后,根據(jù)自己的策略就分發(fā)到對應(yīng)的 Local APIC,咱們八個車間就可以專心處理了,為我們省了不少事兒。
不僅如此,通過這個外包團(tuán)隊,我們八個車間還能向彼此發(fā)起中斷請求,我們把這個叫做處理器間中斷 Inter-Processor Interrupt,簡稱 IPI。
中斷親和性
每當(dāng)網(wǎng)絡(luò)中有數(shù)據(jù)包到來,網(wǎng)卡那家伙就發(fā)送一個中斷消息過來,告訴我們?nèi)ヌ幚怼?/p>
不過最近不知道怎么回事,網(wǎng)絡(luò)數(shù)據(jù)量激增。咱們廠里明明有 8 個車間,他非得一個勁的只給我們發(fā)消息,搞得我們手頭的工作老是被打斷,忙得不可開交。
終于,我忍不住了,去找網(wǎng)卡那家伙理論了一番。不過他告訴我,這也不能怪他,分發(fā)給誰處理,那是 APIC 在負(fù)責(zé)。
想想也是,回頭我就去了 APIC 那里,要求他們分?jǐn)傄稽c給別的車間處理。
APIC 表示這他們做不了主,得讓廠里來決定。
沒過幾天,廠里開了個會,參會的有各車間代表、APIC 負(fù)責(zé)人,還請了操作系統(tǒng)那邊的相關(guān)代表過來。
會上,大家為了此事爭執(zhí)不休。
二號車間虎子:“阿 Q,誰叫你們一號車間是 Bootstrap Processor,你們就多辛苦一點嘛”
三號車間代表:“你這話說的不合適,大家是一個 Team,要互相幫助!要不這樣,既然有這么多單位要聯(lián)系我們,咱就分下工,比如一號車間負(fù)責(zé)網(wǎng)卡,二號負(fù)責(zé)磁盤,我們?nèi)栘?fù)責(zé)鍵盤,以此類推”
五號車間代表:“你想的倒是挺美哦,鍵盤一天能發(fā)多少中斷,網(wǎng)卡一天要發(fā)多少中斷,你凈挑輕松的干。這樣吧,咱就用隨機(jī)分發(fā)進(jìn)行負(fù)載均衡你們覺得怎么樣?”
八號車間代表:“隨機(jī)個啥啊,多麻煩,依我看吶咱 8 個車間就輪流來唄”
這時,領(lǐng)導(dǎo)問操作系統(tǒng)代表有沒有什么建議。
這代表站起身來,推了推眼鏡說到:“幾位有沒有聽過線程的 CPU 親和性?”
大家都搖了搖頭,問到:“這是個什么意思?”
“就是有些線程想綁定在你們之中的某一個核上面執(zhí)行,不希望一會兒在這個核執(zhí)行,一會兒在那個核執(zhí)行”
我接過他的話:“好像是有這么回事兒,之前有遇到過,有個線程一直被分配到我們一號車間,不過我們對這個不用關(guān)心吧,執(zhí)行誰不是干活啊,對我們都一個樣”
代表搖了搖頭,“唉,這可不一樣!你們每個核的一二級緩存都是自己在管理,要是換到別的核,這緩存多半就沒用了,又得重新來建立,這換來換去的豈不是瞎耽誤功夫嘛!對于一般的線程他們倒是不關(guān)心,但是有些線程執(zhí)行大量的內(nèi)存訪問和運算處理,又對性能要求很高的話,那就很在意這個問題了”
我們幾個都恍然大悟,紛紛點頭。
虎子起身問到:“那你們是如何實現(xiàn)這個親和性的呢?這跟我們今天的會議又有什么關(guān)系呢?”
代表繼續(xù)回答說到:“我先回答你的第一個問題。線程調(diào)度是我們操作系統(tǒng)完成的工作,我們提供了 API 接口,線程通過調(diào)用這些接口表明自己的親和性意愿,我們在調(diào)度的時候就能按照他們的意愿把線程分配給你們來執(zhí)行。”
代表喝了一口水接著說到:“我再回答你的第二個問題。既然線程可以有親和性,那中斷也可以按照這個思路來分發(fā)??!APIC 默認(rèn)有一套分發(fā)策略,但是也提供親和性的設(shè)置,可以指定誰哪些核來處理,這樣不用把規(guī)矩定死,靈活可變,豈不更好?”
剛說完,會議室門口突然出現(xiàn)一年輕少年,揮手將操作系統(tǒng)代表喚了出去。
接下來,我們詳細(xì)討論了這種方案的可行性,最后大家一致決定,就照這么辦,我們一起提出了一個叫中斷親和性的東西,操作系統(tǒng)那邊提供一個可配置的入口 smp_affinity,可以通過設(shè)置各處理器核的掩碼來決定中斷交由誰來處理,APIC 回去負(fù)責(zé)落地支持。
有了這套方案,再遇到網(wǎng)絡(luò)高峰期,咱們一號車間的壓力就有辦法緩解了。
我們剛剛達(dá)成一致,操作系統(tǒng)代表返回會議室,神色凝重的說到:“不好意思各位,操作系統(tǒng)那邊有點事情需要趕回去處理一下,先走一步了”。
??????
廣告聲明:文內(nèi)含有的對外跳轉(zhuǎn)鏈接(包括不限于超鏈接、二維碼、口令等形式),用于傳遞更多信息,節(jié)省甄選時間,結(jié)果僅供參考,IT之家所有文章均包含本聲明。