91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

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

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

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

Linux內(nèi)核性能剖析的方法學和主要工具

Linux閱碼場 ? 來源:Linux閱碼場 ? 作者:Linux閱碼場 ? 2022-12-07 15:27 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

計算機科學的先驅(qū)Donald Knuth(高德納)曾經(jīng)說過:“過早的優(yōu)化是萬惡之源”,更詳細的原文如下:“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified.”它向我們揭示了一個道理,我們應(yīng)該首先定位到那3%真正成為瓶頸的代碼,而忽略97%那些“small efficiencies”,所謂“將軍趕路,不打小鬼”,這是我們進行一切性能優(yōu)化的前提。因此,剖析(profiling),成為了性能優(yōu)化中最重要的環(huán)節(jié)之一。

性能剖析,要求我們的思維方式主要是top-down的,我們能全局地從頂部向下的看問題,這就像一個全科醫(yī)生,出了問題后,能大致估摸出一個方向知道是哪個器官可能出了問題。但是,我們同時也必須具備down-top的能力,正如一個??漆t(yī)生,能看到細小器官的癌細胞最終會怎樣向全身發(fā)散,從而危機到人的健康和生命。

系統(tǒng)的性能優(yōu)化不太是一個通過review幾千萬行代碼,發(fā)現(xiàn)問題,然后更正問題優(yōu)化的過程。而更多是一個通過某些剖析手段,把系統(tǒng)當成黑盒子,暴露數(shù)據(jù),top-down地看這個系統(tǒng),在發(fā)掘問題后,再深入到白盒down-top的過程。《魏略》曰:“亮在荊州,以建安初與潁川石廣元、徐元直、汝南孟公威等俱游學,三人務(wù)於精熟,而亮獨觀其大略?!毙阅軆?yōu)化本身,是一個從統(tǒng)帥諸葛亮逐步變身單兵戰(zhàn)神呂布的過程,而你首先必須是統(tǒng)帥。

一、性能剖析的總體認識

下面我們也來一個“觀其大略”的環(huán)節(jié),先“不求甚解”地看一看內(nèi)核性能分析關(guān)注的指標,分析角度和一些其他基本常識。

吞吐

吞吐強調(diào)單位時間里可以做多少有用功。比如,我們會用netperf來評估網(wǎng)絡(luò)的帶寬;用sysbench來評估MySQL的QPS(Queries Per Second)和TPS(Transactions Per Second);用vm-scalability來評估Linux內(nèi)存管理的吞吐性能等;用tbench來評估內(nèi)核調(diào)度器wake-up路徑上的優(yōu)化是否有效等。

為了提高吞吐,我們常常采用的一個方法是橫向拓展硬件或者軟件的規(guī)模,比如增加更多的CPU、使用多線程等。然而世間萬物,不如意者十之八九,不是你愛她多一點,她就一定會愛上你。吞吐的拓展受限于著名的Amdahl's law和Universal Scalability law(USL)。

按照USL,核多(核數(shù)為p),實際的加速倍數(shù)是:

998858c6-75ff-11ed-8abf-dac502259ad0.png

p增大的時候,不僅僅是分子增大,分母也增大,分母σ因子隨著p線性增大,k因子隨著p的平方線性增大。USL的分母中去掉+k*p*(p-1)就是Amdahl's law,所以Amdahl's law并沒有USL完整準確。

其中的σ系數(shù)是contention(核間、多線程間因為競爭等鎖、同步等而不能并行執(zhí)行),k系數(shù)是coherency(核間、多線程之間的協(xié)同形成共識的開銷)。σ系數(shù)比較好理解,比如兩個CPU訪問同一個鏈表,他們需要競爭鎖,假設(shè)平均1秒里面0.1秒在等鎖,則2個cpu實際只有2*0.9=1.8秒在做有用功,而不是2.0。k系數(shù)相對難理解一點,比如我們在CPU0釋放一個spinlock,在ticket spinlock里面,這個spinlock的新值要通過cache同步網(wǎng)絡(luò)同步給系統(tǒng)的每個CPU形成所有CPU對這個新值的一致性理解,這個cache同步的開銷很大,而且隨著p的平方而增大。這就是為什么內(nèi)核針對spinlock不斷在進行優(yōu)化,比如從ticket spinlock變成qspinlock,其實是減小了需要coherency的CPU個數(shù)。

9998adac-75ff-11ed-8abf-dac502259ad0.png

舉一個栗子,軟件的童鞋很可能會天真地以為內(nèi)核的atomic_inc()、TLB flush之類的操作是非常便宜的,其實它們都有嚴重的k因子問題,就是coherency開銷。如果做一個簡單的操作:

lcase A: 100核,100個線程同時做atomic_inc(),做一秒鐘;

lcase B: 10核,10個線程同時做atomic_inc(),做一秒鐘。

case A原子操作的次數(shù)不會是case B的10倍,它實際遠小于10倍,比如實測結(jié)果可能是嚇死你的4倍(當然每個具體的SoC都可能不一樣),等于10倍的硬件目前這個世界還沒有做出來,未來也造不出來。

這些σ系數(shù)、k系數(shù)對服務(wù)器的影響,遠大于對桌面和手機等系統(tǒng),因為服務(wù)器上的p特別大。所以,長期困擾服務(wù)器的問題,比如我從50個cpu變成100個cpu,MySQL的吞吐一定增加了一倍了嗎?不好意思,很可能只是嚇死你的1.3倍,如果運氣不好的話,還可能倒退。

再回到spinlock,大量的文獻顯示,由于ticket spinlock等在核間coherency上的巨大開銷,許多業(yè)務(wù)的性能可隨著CPU核數(shù)量的增大而減小【1】。

99b84946-75ff-11ed-8abf-dac502259ad0.png

最開始核增加的時候,相關(guān)業(yè)務(wù)的性能在提升,到某個拐點后,再增加更多的CPU,性能不升反降,出現(xiàn)了collapse。

延遲

甲骨文的“山”,是一個象形字,它較好地貼合了Linux世界里的延遲模型。Linux世界的延遲往往呈現(xiàn)為這種multi-modal(有多個峰值而不是只分布在一個峰值周圍)或者兩極分化特性。

99cc2a38-75ff-11ed-8abf-dac502259ad0.png

由于這種multi-modal分布的存在,這個時候,我們描述平均值的意義其實不是特別大。比如一個班上有30個學生,其中10個人90分以上(學霸),還有10個人50分以下(學渣),另外還有10個在50-90分之間。我們說這個班的學生平均分60分,其實沒有任何意義,拉馬老師來和我們平均,沒意思的。這個時候,我們需要直方圖來描述這種分布,從而更加直觀地看出來這個班的學霸和學渣比率。

99dc5d54-75ff-11ed-8abf-dac502259ad0.png

如果我們想看一個真實的Linux例子,下面是我的PC在運行“sudo cat /dev/nvme0n1 > /dev/null”的過程中,我看到的BIO(block I/O)的延遲分布:

99ee2976-75ff-11ed-8abf-dac502259ad0.png

我們看到了2個峰值,一個峰值在64us-127us之間;另外一個峰值,則圍繞著1024-2047us分布。當然,還有一個值會偏移地特別遠,比如有2個采樣點,落在了131072us-262143us之間。那2個離群很遠的值,我們一般也稱呼它們?yōu)閛utlier,它們是夜空中最閃亮的星,天生不是凡人。

種種跡象表明,我們僅關(guān)注平均值的意義非常有限。對于偏移中線的部分,在延遲分析領(lǐng)域,我們還特別關(guān)注一個非常重要的概念,tail latency,中文可譯為尾延遲。比如我們說,90%的延遲落在1ms以內(nèi),99%的延遲在10ms以內(nèi),但是還有1%的延遲可能更大,甚至形成一個很長很長的尾巴,可能有的達到了1秒也說不定。在延遲分析領(lǐng)域,我們很可能關(guān)注這些尾部,比如大家一起競爭mutex,那些延遲很大的case,可能會形成手機系統(tǒng)的卡頓,因此丟幀。對于服務(wù)器、電商、云服務(wù)等領(lǐng)域而言,高的尾延遲,會直接影響到企業(yè)的revenue。

9a05bfbe-75ff-11ed-8abf-dac502259ad0.png

延遲的幾個主要可能的來源:

1.進程實際可以運行(TASK_RUNNING),但是由于調(diào)度延遲的原因搶不到CPU;

2.進程同步等待一個I/O動作的完成,這些I/O動作可能是syscall的read/write,也可能是mmap內(nèi)存page fault后的I/O;

3.系統(tǒng)內(nèi)存吃緊,進程陷入direct memory reclaim,直接回收內(nèi)存;

4.進程等其他進程釋放鎖,這里又分2種可能性

a.等鎖隊列比較長,比如等mutex、spinlock,前面已經(jīng)掛了一個連在等,等到自己的時候,心已經(jīng)碎了;

b.等鎖隊列可能不長,但是持有鎖的進程遭遇了情況1、情況2和3,導致長期不放鎖。類似你在等廁位,他卻坐馬桶上看了場電影。

所有的上述不確定情況,都可能形成不確定的tail latency。我們需要某些手段把它剖析和呈現(xiàn)出來。

功耗

內(nèi)核有cpufreq, cpuidle,意識到功耗的調(diào)度器等。這些都致力于在降低功耗的情況下,總體不降低性能。除這些以外,我們也應(yīng)該認識到,降低內(nèi)核本身的CPU利用率,比如內(nèi)存compaction、內(nèi)存swap/reclaim、鎖自旋等的開銷,也能進一步降低功耗。在一個內(nèi)存受限的系統(tǒng)中,我們不能低估內(nèi)核本身的開銷所引起的功耗增加。

比如,我在 qemu上ARM64 Linux-5.19-rc2內(nèi)核,然后運行下面簡單的程序:

9a142a86-75ff-11ed-8abf-dac502259ad0.png

這個程序申請了1GB內(nèi)存,然后fork出來64個進程,其中最原始那個父進程不停讀寫這個1GB的內(nèi)存。代碼gcc編譯結(jié)果a.out。系統(tǒng)的內(nèi)存是900M,并開啟了zRAM交換功能。運行起來后,我們看它的CPU消耗,a.out固然是很大,可是kswapd0這個內(nèi)核線程也是非常大的CPU占用。

9a29dd86-75ff-11ed-8abf-dac502259ad0.png

kswapd0相對我們的有用功a.out,只是輔助的工作,本質(zhì)屬于浪費電。此外,我們的a.out本身占用的接近100%的CPU,也主要耗費在a.out自身的動作上嗎?這個時候我們也有興趣看一下,我們“perf top -p ”一下,我們發(fā)現(xiàn)a.out也有大量的時間落在了內(nèi)核的各種函數(shù)里面:

9a3f5878-75ff-11ed-8abf-dac502259ad0.png

所以從性能分析的角度來說,我們也要把這些紅框部分挖掘出來進行分析優(yōu)化,因為本質(zhì)他們也是純耗電,屬于overhead而不是real work。

90分到100分特別難

在所有的性能優(yōu)化領(lǐng)域,我們都不得不正視一點,無論你多么地不愿意:就是前期的優(yōu)化是相對比較容易的,越到后來越難。一個考10分的學渣,也許經(jīng)過努力比較容易考到60分,再繼續(xù)挑燈夜戰(zhàn),可能也能考到90,但是哪怕本著“只要學不死,就往死里學”的極限熱情,他也不一定能從90分考到100分,當然它可能考到91分。

9a618524-75ff-11ed-8abf-dac502259ad0.png

努力到一定程度后,有沒有可能越努力成績越差呢?我覺得是可能的,因為Universal Scalability law(USL),學麻了容易走火入魔,反而出現(xiàn)性能的collapse。

成年人最重要的心理素質(zhì)是學會和自己的平凡和解,打牌輸了不要賴著不走再打一局不如隔天換個場子打。性能優(yōu)化也是一樣的,在某個角度已經(jīng)搞到了91分,這個時候繼續(xù)鉆牛角尖的代價可能就比較大了。也許我們可以換另外一個角度,來做個從30分到91分的過程,最終實現(xiàn)總成績91+91=182分,而不是100+30=130分。


在總成績182的情況下,再去追求總成績200,心態(tài)和效率都高很多。

off-cpu和on-cpu分析同樣重要

當我們分析代碼在CPU的耗時花費在哪里的時候,我們關(guān)心系統(tǒng)的on-cpu profiling,但是,當我們關(guān)注延遲等問題的時候,我們不僅要關(guān)注on-cpu profiling,更多的時候,我們需要關(guān)注off-cpu profiling。off-cpu profiling的目的在于全面地評估進程不在CPU上面跑的時候,因為什么原因被調(diào)度出去。off-cpu profiling完整地打印出進程離開CPU的原因的調(diào)用棧和時間分布,比如off-cpu發(fā)生在等鎖(如mutex和rwsem)、等I/O完成、被調(diào)度搶占等情況。

性能profiling應(yīng)同時著眼于on-cpu和off-cpu這兩種情況。這個和優(yōu)化我們的工作效率是一樣的,我們既要上班時候盡可能降低CPU消耗,on-cpu的時候少做純耗電的無用功;也要看看是什么原因引起我們上班的時候釣魚劃水,把引起我們off-cpu的原因分析出來從而減少摸魚。

二、on-cpu分析

on-cpu分析主要著眼于2個點:一是找到占用CPU大的熱點代碼;二是提高單位運行時間內(nèi),CPU執(zhí)行有效指令的條數(shù)。前一個點重心在于降低CPU利用率,后一個點則著重于提高CPU的工作效率。下面層層展開,展開過程中會直接介紹相關(guān)的工具。

on-cpu火焰圖

我們看到前述代碼中,kswapd0占據(jù)了57.7%的CPU。所以我們現(xiàn)在特別感興趣,它的CPU的具體走向,火焰圖可進行一個比較完整的呈現(xiàn)。假設(shè)kswapd0的PID是54,下面我們抓取內(nèi)核線程54的信息:

9a715abc-75ff-11ed-8abf-dac502259ad0.png

我們把采樣到的數(shù)據(jù),通過火焰圖工具進行繪制:

9a805a9e-75ff-11ed-8abf-dac502259ad0.png

我們得到如下火焰圖:

9a8f61e2-75ff-11ed-8abf-dac502259ad0.png

火焰圖上我們發(fā)現(xiàn),kswapd的時間有小部分發(fā)生在swap_writepage向zRAM寫被替換的頁面,而大部分發(fā)生在判斷頁面是否被訪問的folio_reference_one(),以及頁面向zRAM寫之前unmap這個頁面后的ptep_clear_flush()這2個動作上面。

你也許會想到要去減少folio_reference_one()和ptep_clear_flush()上面的開銷,這是一個剖析和發(fā)現(xiàn)的過程。

CPU消耗比例分布

火焰圖固然呈現(xiàn)了相關(guān)函數(shù)的CPU比例,但是,很多時候我們生成報告,尤其是向社區(qū)發(fā)patch,我們需要發(fā)送文字版的優(yōu)化報告,這些報告可以突出CPU熱點在哪里。這個時候,我們可以用perf report的功能。

9a9f0dea-75ff-11ed-8abf-dac502259ad0.png

啥也不說了,盯著perf report里面排名第1,第2的整起來。相關(guān)的這種數(shù)據(jù)報告在Linux社區(qū)非常常見,比如MGLRU的patch 【2】里面就列出了MGLRU中某一特性優(yōu)化前后的CPU消耗對比數(shù)據(jù):

9abf6fcc-75ff-11ed-8abf-dac502259ad0.png

我們看到屬于overhead的page_vma_mapped_walk()的減小,但是屬于lzo1x_1_do_compress()的real work的增大。所以,我們看數(shù)據(jù)說話,沒有數(shù)據(jù)支撐的性能優(yōu)化,是很難形成任何說服力的。這也就是為什么我們在內(nèi)核社區(qū)發(fā)性能優(yōu)化的patch,必然會被要求大量benchmark數(shù)據(jù)支撐。

最后一公里

前面我們發(fā)現(xiàn)try_to_unmap()后調(diào)用的ptep_clear_flush()是熱點函數(shù),但是它熱在哪里,具體熱在哪一行代碼呢?這個時候,我們需要進一步“perf annotate ptep_clear_flush”。

9ad44e74-75ff-11ed-8abf-dac502259ad0.png

從annotate的結(jié)果可以看出,至少,在筆者運行的qemu平臺上,tlbi附近的開銷是非常大的,其他的代碼開銷幾乎可以忽略不計。當然,真實的ARM64硬件上,tlbi也絕對不便宜。

中斷屏蔽的問題

在一個類似如下spin_lock_irqsave()、spin_unlock_irqrestore()的區(qū)間里,由于采樣的中斷都是被屏蔽的,所以中間perf的采樣結(jié)果,都會在spin_unlock_irqrestore()開啟中斷的這一刻爆出來,導致ARM64平臺下,采樣的熱點落在類似spin_unlock_irqrestore()這樣的地方。這是不準確的。

9affd9fe-75ff-11ed-8abf-dac502259ad0.png

我們在調(diào)試時,可以使能ARM64_PSEUDO_NMI選項,并傳遞irqchip.gicv3_pseudo_nmi=1這樣的bootargs參數(shù)。這樣,內(nèi)核會用GIC的高優(yōu)先級中斷模擬NMI,在local_irq_disable()、spin_lock_irqsave()、spin_lock_irq()這樣的API里面只是屏蔽低優(yōu)先級中斷。

9b23bc34-75ff-11ed-8abf-dac502259ad0.png

舉一個典型的栗子,ARM64 IOMMU(SMMU)的map/unmap開銷大,導致dma_map_single/sg, dma_unmap_single/sg這些APIs在開啟IOMMU的情況下,吞吐率不高。這個時候,我們通過前面的火焰圖、CPU利用率分布報告很可能已經(jīng)抓到了熱點在drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c【3】的arm_smmu_cmdq_issue_cmdlist()這個函數(shù),但是這個函數(shù)長成這個樣子,進去的時候就關(guān)中斷,出來的時候才開中斷:

9b338b00-75ff-11ed-8abf-dac502259ad0.png

這個時候,你不開啟irqchip.gicv3_pseudo_nmi=1是不可能perf annonate出來這個函數(shù)哪句話是熱點的,所有熱點都會落在末尾的local_irq_restore()這句話。但是開啟后,你才會抓到真正的熱點:

9b4b735a-75ff-11ed-8abf-dac502259ad0.png

CPU執(zhí)行效率topdown分析

CPU利用率相等的情況下,執(zhí)行效率是不是一樣的呢?比如都是一秒里面干0.5秒的活,CPU利用率50%,干出來的活是一樣多嗎?不是的,現(xiàn)代計算機系統(tǒng)普遍采用多發(fā)射、流水線、分支預(yù)測、預(yù)取、亂序投機執(zhí)行等各種復雜機制,這使得同樣時間段內(nèi)能實際執(zhí)行的有效指令條數(shù),會是可變的。有兩個非常重要的概念值得所有人關(guān)注:

CPI:(Cycles Per Instruction)每個指令要多少周期。

IPC:(Instructions Per Cycle)每個周期執(zhí)行多少指令。

CPI和IPC為反比例關(guān)系。在同樣CPU利用率的情況下,我們追求盡可能高的IPC。比如1個代碼跑起來IPC是2.0,另外一個1.0,那么意味著同樣的時間段,前者執(zhí)行的指令是后者的2倍,CPU執(zhí)行指令更順暢,stalled(被添堵、處理器空轉(zhuǎn))的環(huán)節(jié)更少。

比如我在我的PC上面運行l(wèi)s,可以看到IPC是0.9:

9b5f5e4c-75ff-11ed-8abf-dac502259ad0.png

比如運行g(shù)cc main.c,可以看到IPC是1.36:

9b789dd0-75ff-11ed-8abf-dac502259ad0.png

Ahmand Yasin在它的IEEE論文《A top-down method for performance analysis and counter architercture》中,革命性地給出了一個從CPU指令執(zhí)行的順暢程度來評估和發(fā)現(xiàn)瓶頸的方法,允許我們從黑盒的角度以諸葛孔明“隆中對”式的格局來看問題。

9b8baaf6-75ff-11ed-8abf-dac502259ad0.png

現(xiàn)在處理器,一般在4個方面占用流水線的時間,而top-down方法,可以黑盒地呈現(xiàn)軟件在CPU上面運轉(zhuǎn)的時候,CPU的流水線究竟在干什么。

Front End Bound(前端依賴): 處理器的前端主要完成指令的譯碼,把獲取的指令翻譯為一系列的micro-ops(μops)。當CPU stalled在Front End,通常意味著CPU在取指慢(比如icache miss、解釋執(zhí)行等),或者復雜指令的翻譯過程由于μops cache不命中等原因而變地漫長。Front End stalled多,意味著前端無法及時給后端“喂飽”μops。目前主流的x86處理器,每個cycle可以給Back End喂4個指令,如果Back End也及時執(zhí)行的話,IPC最高可達4.0。

Back End Bound(后端依賴):處理器的后端主要完成前端“喂”過來的μops的執(zhí)行,執(zhí)行的過程可能涉及讀寫操作數(shù)(load/store)、對操作數(shù)進行加減乘除各種運算之類。Back End Bound又可再細分為2類,core bound意味著軟件更多依賴于微指令的處理能力;memory bound意味著軟件更加依賴CPU L1~L3緩存和DRAM內(nèi)存性能。當CPU stalled在Back End,通常意味著復雜運算指令延遲大,或操作數(shù)從memory(包括cache和DDR)獲取的延遲大,導致部分pipeline slots為空(stall)。

Retiring:μops被執(zhí)行完成,最終的retire動作,提交結(jié)果到寄存器或者內(nèi)存。

Bad Speculation:處理器雖然在干活,但是投機執(zhí)行的指令可能沒有用。比如分支本身應(yīng)該進“else”的,預(yù)測的結(jié)果卻進了“if”執(zhí)行錯誤的分支,雖然沒有stall,但是這些錯誤分支里面的指令實際白白執(zhí)行了不會retire,所以也浪費了pineline的時間。這里有一個基本常識,比如“if(a) do x; else do y;”,處理器并不是等待a的判決結(jié)果后,再去做x或者y,而是先根據(jù)歷史情況投機執(zhí)行x或者y,當然這個投機有可能出錯。

注意Front End Bound、Back End Bound和我們平時說的軟件是CPU bound還是I/O Bound是相似概念,比如CPU bound的軟件更加依賴計算能力并對CPU性能敏感(比如編譯Linux內(nèi)核、編譯Android),I/O bound的軟件更加依賴于I/O動作本身并對I/O性能敏感(比如你把硬盤dd if=/dev/sda1 of=xxx到xxx地方去)。

我們把CPU pipeline上的任何一個硬件資源想象成一個pipeline slots,假設(shè)CPU可以同時處理4條μops,下圖共有40個slots,如果所有slots都做有用功,μops都能retiring,則IPC為4.0:

9bad9576-75ff-11ed-8abf-dac502259ad0.png

假設(shè)其中的20個slots要么是empty沒活干(stalled),或者做的是無用功(分支預(yù)測錯誤等情況),那么它的IPC可能就是2.0了。

9bbefa78-75ff-11ed-8abf-dac502259ad0.png

Intel處理器架構(gòu)下,已經(jīng)將top-down完全地工具化,有專門的top-down工具,有的甚至已經(jīng)圖形化了,比如VTune Profiler里面就有類似功能【4】,可以具體化到每一個特定函數(shù)的Front-end Bound、Back-End Bound、Bad Speculation、Retiring等的情況:

9bd3a630-75ff-11ed-8abf-dac502259ad0.png

大家從上表可以看出,基本retiring的比例越低,證明pipeline slots的stall越大,CPI也就越高(IPC越低)。比如,refresh_potential()的CPI高達3.589,主要是它的Back-End Bound嚴重,其中Memory Bound高達73.2%,所以優(yōu)化這個函數(shù),要多從cache命中率(L1,L2,L3)、DDR帶寬/延遲角度考慮。而優(yōu)化sort_basket()函數(shù)則要多從分支預(yù)測優(yōu)化角度考慮,因為它的Bad Speculation高達50.4%。

有的童鞋對Bad Speculation可能還是不太明白,下面我們通過一個代碼栗子:

9be6af14-75ff-11ed-8abf-dac502259ad0.png

這個里面有個隨機數(shù)r = rand(),會極大地破壞分支預(yù)測的準確性,所以topdown的結(jié)果如下:

9bf70fe4-75ff-11ed-8abf-dac502259ad0.png

如果我們把里面的rand()函數(shù)變成自己的版本,讓分支結(jié)果并不那么隨機:

9c0d88f0-75ff-11ed-8abf-dac502259ad0.png

再次topdown,結(jié)果則是(retiring很大,綠色友好程序):

9c1b6e66-75ff-11ed-8abf-dac502259ad0.png

此時的IPC也很大,達到3.49,比較接近4.0了:

9c3b0a28-75ff-11ed-8abf-dac502259ad0.png

Intel方面,腳本化的工具則有pmu-tools【5】。比如筆者在自己的X86 PC(內(nèi)存24GB)上面開啟zRAM后運行如下代碼:

9c5ce13e-75ff-11ed-8abf-dac502259ad0.png

假設(shè)kswapd的PID是202,我們捕獲以下kswapd的bound情況:

9c6ee776-75ff-11ed-8abf-dac502259ad0.png

由此我們可以看出,在上述場景下,kswapd跑起來主要是一個Back End Bound,其中Back End Bound里面的memory和core bound各占25.1%和19.3%,至于memory bound的部分,它又可以細分到L1,L2,L3 cache更深層次的原因。

我們現(xiàn)在覺得memory bound是上述場景下kswapd的大頭,我們實際也可以采樣下kswapd的cache-misses。簡單運行“sudo perf top -e cache-misses -p 202”命令看一下,cache misses率最高的是LZ4_compress_fast_extState()、memset_erms()和isolate_lru_pages()。你也許可以怎么去優(yōu)化這些函數(shù),從而減小它們的Back-End bound的部分,提高kswapd的IPC。

9c8dd794-75ff-11ed-8abf-dac502259ad0.png

Intel的平臺享受上面的工具化優(yōu)勢。其他平臺的童鞋也不必懊惱,perf本身也具有topdown能力,perf stat后面有個參數(shù)是--topdown:

9c9e722a-75ff-11ed-8abf-dac502259ad0.png

查看Intel童鞋的這個patch【6】,最新版本的perf實際也可以支持td-level=2這樣更細粒度的topdown打?。?/p>

9cb239e0-75ff-11ed-8abf-dac502259ad0.png

整個on-cpu分析的過程是top-down的,過程中的某些步驟也是topdown的,我們用一個流程圖來描述:

9cc17ee6-75ff-11ed-8abf-dac502259ad0.png

三、off-cpu分析

off-cpu分析更多關(guān)注延遲問題,所以我們首先要獲知延遲的分布,這個時候我們最好使用直方圖。之后,我們可以過度到用off-cpu火焰圖等進一步分析off-cpu在等什么,而在lock contention的場合,則可以使用perf lock來進一步進行鎖的分析。

直方圖

直方圖深入人心,哪怕什么工具都沒有,純粹地用Linux內(nèi)核也可以劃出直方圖。這個功能位于菜單tracer->Histogram triggers,通過內(nèi)核tracepoints實現(xiàn)。

9cd605b4-75ff-11ed-8abf-dac502259ad0.png

下面我們隨便舉個例子,看看mm/vmscan.c中shrink_inactive_list()一般回收page個數(shù)的分布。注意,這純粹是一個栗子,不對應(yīng)任何的實際工程。

9ce6d5e2-75ff-11ed-8abf-dac502259ad0.png

在直方圖中,我們關(guān)心2個點,一個是key,一個是value。比如我們以回收頁面的個數(shù)為key,回收到這一key值頁面?zhèn)€數(shù)的次數(shù)為value。

我們在include/trace/events/vmscan.h和mm/vmscan.c中增加這個trace:

9cf380bc-75ff-11ed-8abf-dac502259ad0.png

trace_mm_vmscan_nr_reclaimed(nr_reclaimed, 1);這句話表示回收nr_reclaimed個頁面的次數(shù)增加1。

現(xiàn)在我們使能tracer,以nr_reclaimed為key, times為value,按照times降序排列:

9d05bc78-75ff-11ed-8abf-dac502259ad0.png

運行系統(tǒng),觸發(fā)一些內(nèi)存回收動作,采樣到一些值后,直接讀取直方圖:

9d16a5b0-75ff-11ed-8abf-dac502259ad0.png

從直方圖可看出,實驗場景中,回收到32個pages的機會最多,占據(jù)76598次,其次是回收到1個、0個和2個的。

下面我們把所有采樣復原,改為依據(jù)nr_reclaimed升序顯示:

復原:

9d2dd050-75ff-11ed-8abf-dac502259ad0.png

開啟新的采樣:

9d3d54ee-75ff-11ed-8abf-dac502259ad0.png

運行系統(tǒng),觸發(fā)一些內(nèi)存回收動作,采樣到一些值后,直接讀取直方圖:

9d4b6d40-75ff-11ed-8abf-dac502259ad0.png

有的童鞋說,我現(xiàn)在關(guān)注的是延遲時間的分布,不是nr_reclaimed。這完全不影響我們的原理,比如latency單位是us,我想搜集0-5ms, 5-10ms, 10-15ms, 15-20ms各個檔次的分布,我只需要trace:

trace_xxx_sys_yyy_latency(latency/5000, 1);

后面在hist中,0-5ms會是一行,5-10ms會是一行,依此類推。另外,內(nèi)核里面統(tǒng)計延遲可用類似的代碼邏輯(來源于kernel/dma/map_benchmark.c的map_benchmark_thread函數(shù)):

9d6fab74-75ff-11ed-8abf-dac502259ad0.png

eBPF/BCC中本身內(nèi)嵌多個直方圖工具,可滿足許多常見的生活必須,比如之前演示的biolatency,還有這些已經(jīng)自帶:

bitehist.py: Block I/O size histogram.

argdist: Display function parameter values as a histogram or frequency count.

bitesize: Show per process I/O size histogram.

btrfsdist: Summarize btrfs operation latency distribution as a histogram.

cpudist: Summarize on- and off-CPU time per task as a histogram.

dbstat: Summarize MySQL/PostgreSQL query latency as a histogram.

ext4dist: Summarize ext4 operation latency distribution as a histogram.

funcinterval: Time interval between the same function as a histogram.

runqlat: Run queue (scheduler) latency as a histogram.

runqlen: Run queue length as a histogram.

xfsdist: Summarize XFS operation latency distribution as a histogram.

zfsdist: Summarize ZFS operation latency distribution as a histogram.

funclatency這個筆者也經(jīng)常用,比如看一下vfs_read()這個函數(shù)的執(zhí)行時間分布,只需要把函數(shù)名加在funclatency之后就好:

9d849fe8-75ff-11ed-8abf-dac502259ad0.png

我們看到vfs_read()在實驗場景,一般延遲是8-16us之間占據(jù)第一名。但是偶爾也能大到驚人的4294967296ns,也就是4.2秒,從直方圖最后一行可以看出,這些可能就是outlier了。

eBPF/BCC可以依附于kprobe、tracepoints上,在eBPF/BCC上定制直方圖,只用寫非常簡單的腳本即可,因為直方圖是其本身內(nèi)嵌的功能。比如在patch【7】中,筆者想知道kernel/sched/fair.c的select_idle_cpu()在進程被喚醒的時候,統(tǒng)計選中與target同cluster idle CPU,不同cluster idle CPU和沒找到idle cpu的比例,只需要寫一個簡單的腳本:

9dbac00a-75ff-11ed-8abf-dac502259ad0.png

這個腳本的關(guān)鍵是涂了紅色的三行,定義了一個直方圖對象dist,然后就在里面通過dist.increment(e)增加采樣點,最后通過b["dist"].print_linear_hist("idle")把直方圖畫出來:

9dcdc4a2-75ff-11ed-8abf-dac502259ad0.png

eBPF/BCC里面有許多直方圖的例子,我們定制自己的直方圖的時候,依葫蘆畫瓢就好。

off-cpu火焰圖

實際上,eBPF/BCC的代碼倉庫已經(jīng)寫好了off-cpu工具,可以直接拿來用:

https://github.com/iovisor/bcc/blob/master/tools/offcputime.py

它的原理是抓捕內(nèi)核進行進程上下文切換的時間和backtrace,比如可以對finish_task_switch()內(nèi)核函數(shù)施加探針。因為我們在這個點可以知道什么進程被切換走了,什么進程被切換回來的,結(jié)合這些點的backtrace搜集,我們就可以得到睡眠和喚醒的調(diào)用棧,以及時間差??梢栽谶@個函數(shù)加tracepoint,但是沒有tracepoint的情況下,我們也可以直接attach kprobe探針。

finish_task_switch()的函數(shù)原型是:

9ddf66da-75ff-11ed-8abf-dac502259ad0.png

可見參數(shù)prev是被切換走的進程,而我們通過current可以拿到當前的進程,也即我們切入的進程。通過下面的算法,即可求出整個off-cpu區(qū)間的時間和backtrace:

9df17820-75ff-11ed-8abf-dac502259ad0.png

通過在內(nèi)核finish_task_switch()的kprobe點上插入eBPF/BCC代碼來完成這個算法,這樣不需要修改和重新編譯內(nèi)核。之后,我們可以把eBPF/BCC捕獲的數(shù)據(jù),借助flamegraph工具,繪制出off-cpu火焰圖。

下面給一個非常簡單的案例,在我的Ubuntu x86 PC上面運行以下代碼,創(chuàng)建32個進程,每個進程申請1G內(nèi)存,然后循環(huán)執(zhí)行:16字節(jié)對齊的時候?qū)懭胍粋€字節(jié),1MB對齊的時候睡眠30us。

9e002a46-75ff-11ed-8abf-dac502259ad0.png

測試內(nèi)核是5.11.0-49-generic,內(nèi)核未開啟搶占,但是允許PREEMPT_VOLUNTARY:

# CONFIG_PREEMPT_NONE is not set

CONFIG_PREEMPT_VOLUNTARY=y

# CONFIG_PREEMPT is not set

測試的環(huán)境開啟了zRAM的swap,但是關(guān)閉了磁盤相關(guān)的swap:

9e0f8d9c-75ff-11ed-8abf-dac502259ad0.png

捕獲a.out 30秒的off-cpu數(shù)據(jù),并繪制火焰圖。

9e1f6082-75ff-11ed-8abf-dac502259ad0.png

得到如下火焰圖:

9e2f5c08-75ff-11ed-8abf-dac502259ad0.png

從以上火焰圖可以看出,a.out的延遲主要是3個方面原因:

發(fā)生在其用戶態(tài)代碼本身調(diào)用的nanosleep()上;

發(fā)生在page_fault的處理上;

時間片到期后, timer中斷進來,把它切換走。

我們把這3個塊分別畫3個圓圈:

9e46968e-75ff-11ed-8abf-dac502259ad0.png

火焰圖的縱向是backtrace,橫向是每一種情況的off-cpu時間,橫向越寬代表這個調(diào)用stack上的off-cpu時間越久。

假設(shè)我們shrink_inactive_list()這個函數(shù)特別感興趣,則可點擊shrink_inactive_list()這個函數(shù),單獨查看這個函數(shù)的off-cpu細節(jié),我們發(fā)現(xiàn),它其中一半的off-cpu是因為它自己調(diào)用了一個msleep(),還有很大一部分發(fā)上在它主動call了_cond_resched(),然后CPU被別人搶走;如果我們關(guān)注mutex_lock() 的延遲,則顯然發(fā)生在shrink_inactive_list() -> shrink_page_list() -> add_to_swap -> get_swap_pages() -> mutex_lock()這個路徑上。

9e5c06d6-75ff-11ed-8abf-dac502259ad0.png

如果我們把焦點移到kswapd,我們還是運行上面的a.out代碼,但是我們捕獲和分析的對象換為kswapd。捕獲kswapd的off-cpu數(shù)據(jù)30秒并繪制off-cpu火焰圖。

9e80fe00-75ff-11ed-8abf-dac502259ad0.png

繪制出來的kswapd的off-cpu火焰圖如下:

9e92a0d8-75ff-11ed-8abf-dac502259ad0.png

可見多數(shù)延遲發(fā)生在kswapd各種路徑下(比如shrink_inactive_list -> shrink_page_list路徑)主動調(diào)用_cond_resched()出讓CPU,還有一部分延遲發(fā)生在最右邊的shrink_slab的i915顯卡驅(qū)動的slab shrink,點擊放大它:

9ebbdfac-75ff-11ed-8abf-dac502259ad0.png

從上圖可以看出,我們在內(nèi)存回收shrink_slab()的時候,被i915驅(qū)動的i915_gem_shrink()堵住了,而i915_gem_shrink()被一個mutex_lock_interruptible()堵住了,所以i915驅(qū)動持有的一個mutex實際上給shrink_slab()是添堵了。

特別有意思的是,這個off-cpu火焰圖,還可以變成雙層的off-wake火焰圖。比如A進程等一個鎖睡眠了,B進程是持有鎖的人,B喚醒了A,在off-wake火焰圖上,它會以雙層調(diào)用棧的形式進行展示。比如在a.out引起匿名頁頻繁swap的情況下,抓一下kswapd的off-wake火焰圖:

9ed48e8a-75ff-11ed-8abf-dac502259ad0.png

得到的圖如下:

9ee24746-75ff-11ed-8abf-dac502259ad0.png

從圖上可以完整看出,kswapd off-cpu的原因和喚醒者。比如畫紅圈的區(qū)域,kswapd因為調(diào)用kswapd_try_to_sleep()而主動進入睡眠,a.out在swap in的過程中do_swap_page()因而需要alloc_pages()的時候因為申請內(nèi)存的壓力,喚醒了kswapd內(nèi)核線程。天藍色的是kswapd,淡藍色的是喚醒者。喚醒者的調(diào)用棧是從上到下,off-cpu的kswapd的調(diào)用棧是從下到上,中間通過灰色隔離帶隔開。這種描述方式,確實看起來比較驚艷有木有?

9f05798c-75ff-11ed-8abf-dac502259ad0.png

Lock Contention分析

在使能內(nèi)核CONFIG_LOCKDEP 和CONFIG_LOCK_STAT 選項的情況下,我們可以通過perf lock來進行l(wèi)ock的contention分析。其實perf lock主要是利用了內(nèi)核一系列的鎖的tracepoints,比如trace_lock_acquired(lock, ip)、trace_lock_acquired(lock, ip)、trace_lock_release(lock, ip)等。

在我運行一個匿名頁頻繁swap out/in的系統(tǒng)里,抓取lock情況:

9f1c7be6-75ff-11ed-8abf-dac502259ad0.png

然后生成報告:

9f2cc97e-75ff-11ed-8abf-dac502259ad0.png

看起來&rq->__lock、ptlock_ptr(page)、&lruvec->lru_lock的競爭比較激烈。尤其是&lruvec->lru_lock,由于contention比較多,total wait時間比較大。這里要特別留意一點,lock contention不一定是off-cpu的,可能也有on-cpu的,對于mutex, rwsem更多是off-cpu的;spinlock,則更多是on-cpu的。

對于off-cpu以及相關(guān)的延遲問題,我們需要通過直方圖獲知延遲分布、off-cpu/off-wakeup火焰圖獲知off-cpu的原因和喚醒者,如果是鎖競爭的情況,則進一步通過內(nèi)核perf lock剖析鎖競爭。

9f3e4bf4-75ff-11ed-8abf-dac502259ad0.png

四、總結(jié)

性能優(yōu)化經(jīng)常是一個全棧的工作,對工程師的要求也比較高。它是一個很難用一篇文章完整描述清楚的話題,所以本文更多只是起一個提綱挈領(lǐng)的作用,許多話題有待以后有機會進一步展開。文中疏漏,在所難免,還請讀者朋友海涵。最后推薦給親愛的讀者朋友們2本書:

BrenDan Gregg的《System Performance Enterprise and the Cloud(Second Edition)》;

Denis Bakhvalor的《Performance Analysis and Tuning on Modern CPUs》

審核編輯 :李倩

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

    關(guān)注

    68

    文章

    11288

    瀏覽量

    225199
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11772

    瀏覽量

    219117
  • 內(nèi)存管理
    +關(guān)注

    關(guān)注

    0

    文章

    171

    瀏覽量

    14887

原文標題:Linux內(nèi)核性能剖析的方法學和主要工具

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

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

掃碼添加小助手

加入工程師交流群

    評論

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

    Linux內(nèi)核驅(qū)動開發(fā)的技術(shù)核心精要

    嵌入式Linux驅(qū)動開發(fā)是連接硬件與操作系統(tǒng)的關(guān)鍵環(huán)節(jié)。隨著內(nèi)核演進(如Linux 6.13)和硬件復雜度提升,開發(fā)者需掌握并發(fā)控制、中斷分層、內(nèi)存管理、設(shè)備樹、調(diào)試工具等核心知識。本
    發(fā)表于 03-10 13:56

    進迭時空 Upstream | K3 獲得 Linux 7.0 內(nèi)核原生支持

    2026年2月22日,隨著Linux內(nèi)核正式發(fā)布v7.0-rc1版本,全球開源社區(qū)迎來了RISC-V生態(tài)的歷史性跨越。進迭時空(SpacemiT)研發(fā)的高性能RISC-VAICPU芯片K3作為全球首
    的頭像 發(fā)表于 02-27 18:10 ?1.1w次閱讀
    進迭時空 Upstream | K3 獲得 <b class='flag-5'>Linux</b> 7.0 <b class='flag-5'>內(nèi)核</b>原生支持

    Linux內(nèi)核的“心跳”:jiffies如何為系統(tǒng)計時?

    Linux 內(nèi)核的世界里,有一個默默工作的 "計時器"——jiffies。它不像我們手機上的時鐘那樣顯示年月日,卻掌控著內(nèi)核中絕大多數(shù)時間相關(guān)的操作:從進程調(diào)度到設(shè)備驅(qū)動的定時檢查,都離不開它的身影。
    的頭像 發(fā)表于 02-04 16:27 ?843次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>的“心跳”:jiffies如何為系統(tǒng)計時?

    內(nèi)核配置項引發(fā)網(wǎng)絡(luò)性能下降的深度剖析

    在嵌入式系統(tǒng)開發(fā)中,內(nèi)核配置對系統(tǒng)性能起著關(guān)鍵作用。近期在對基于 Rockchip 平臺的 Linux 內(nèi)核配置調(diào)試時,發(fā)現(xiàn)三個內(nèi)核跟蹤器配
    的頭像 發(fā)表于 02-01 16:48 ?1693次閱讀
    <b class='flag-5'>內(nèi)核</b>配置項引發(fā)網(wǎng)絡(luò)<b class='flag-5'>性能</b>下降的深度<b class='flag-5'>剖析</b>

    Linux系統(tǒng)性能調(diào)試工具—strace

    今天給大家分享一個linux內(nèi)核自帶的調(diào)試工具,該工具可用于查看和定位系統(tǒng)問題,進程運行過程探索,進行進程監(jiān)控,對每個系統(tǒng)調(diào)用都可以監(jiān)測,有助于我們優(yōu)化系統(tǒng)
    的頭像 發(fā)表于 01-30 17:03 ?1926次閱讀
    <b class='flag-5'>Linux</b>系統(tǒng)<b class='flag-5'>性能</b>調(diào)試<b class='flag-5'>工具</b>—strace

    Linux系統(tǒng)內(nèi)核參數(shù)調(diào)優(yōu)實戰(zhàn)指南

    Linux 內(nèi)核參數(shù)調(diào)優(yōu)是系統(tǒng)性能優(yōu)化的核心環(huán)節(jié)。隨著云原生架構(gòu)的普及和硬件性能的飛速提升,默認的內(nèi)核參數(shù)配置往往無法充分發(fā)揮系統(tǒng)潛力。在高
    的頭像 發(fā)表于 01-28 14:27 ?471次閱讀

    Linux-RT特點及簡單應(yīng)用

    無法滿足實時性要求。Linux-RT通過對Linux內(nèi)核進行調(diào)整和優(yōu)化,以提供更可預(yù)測、更低延遲的實時性能。 Linux-RT的
    發(fā)表于 12-05 07:37

    基于 DR1M90 的 Linux-RT 內(nèi)核開發(fā):從編譯配置到 GPIO / 按鍵應(yīng)用實現(xiàn)(1)

    本手冊由創(chuàng)龍科技研發(fā),針對 DR1M90,詳述 Linux-RT 實時內(nèi)核開發(fā):含實時性測試(LinuxLinux-RT 對比、CPU 空載 / 滿負荷 / 隔離狀態(tài)測試)、
    的頭像 發(fā)表于 12-02 10:38 ?1199次閱讀
    基于 DR1M90 的 <b class='flag-5'>Linux</b>-RT <b class='flag-5'>內(nèi)核</b>開發(fā):從編譯配置到 GPIO / 按鍵應(yīng)用實現(xiàn)(1)

    RK3506開發(fā)板Xenomai內(nèi)核RT-Linux實時性系統(tǒng)適配教程與性能實測,實測僅7μs穩(wěn)定延時

    本文基于觸覺智能RK3506核心板/開發(fā)板,介紹Xenomai內(nèi)核RT-Linux實時性系統(tǒng)適配,并附性能實測。簡介與實測數(shù)據(jù)Xenomai簡介XEnomai是一個實時子系統(tǒng),可與Linux
    的頭像 發(fā)表于 09-18 14:21 ?1433次閱讀
    RK3506開發(fā)板Xenomai<b class='flag-5'>內(nèi)核</b>RT-<b class='flag-5'>Linux</b>實時性系統(tǒng)適配教程與<b class='flag-5'>性能</b>實測,實測僅7μs穩(wěn)定延時

    【米爾NXP i.MX 91開發(fā)板評測】移植和運行RT-Linux,實時性能測試

    介紹 實時性系統(tǒng)應(yīng)用廣泛,在工業(yè)自動化、醫(yī)療設(shè)備、汽車電子等領(lǐng)域扮演著十分重要的角色,我們用i.MX91開發(fā)板來移植運行RT-Linux,看看它的實時性能表現(xiàn)如何 實時補丁 下載并應(yīng)用RT補丁
    發(fā)表于 09-01 10:11

    Linux內(nèi)核參數(shù)調(diào)優(yōu)方案

    在高并發(fā)微服務(wù)環(huán)境中,網(wǎng)絡(luò)性能往往成為K8s集群的瓶頸。本文將深入探討如何通過精細化的Linux內(nèi)核參數(shù)調(diào)優(yōu),讓你的K8s節(jié)點網(wǎng)絡(luò)性能提升30%以上。
    的頭像 發(fā)表于 08-06 17:50 ?976次閱讀

    如何單獨編譯linux內(nèi)核?

    那套sdk?純linux sdk編譯方法見readmehttps://github.com/kendryte/k230_linux_sdk/ make linux
    發(fā)表于 07-11 08:06

    如何配置和驗證Linux內(nèi)核參數(shù)

    Linux系統(tǒng)運維和性能優(yōu)化中,內(nèi)核參數(shù)(sysctl)的配置至關(guān)重要。合理的參數(shù)調(diào)整可以顯著提升網(wǎng)絡(luò)性能、系統(tǒng)穩(wěn)定性及資源利用率。然而,僅僅修改參數(shù)是不夠的,如何驗證這些參數(shù)是否生
    的頭像 發(fā)表于 05-29 17:40 ?1172次閱讀

    Linux主要性能有哪些?

    都有確定的用途。它支持32位和64位硬件,能運行主要的unix工具軟件、應(yīng)用程序和網(wǎng)絡(luò)協(xié)議。linux繼承了unix以網(wǎng)絡(luò)為核心的設(shè)計思想,是一個性能穩(wěn)定的多用戶網(wǎng)絡(luò)操作系統(tǒng)。
    的頭像 發(fā)表于 04-30 18:09 ?687次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>主要</b>的<b class='flag-5'>性能</b>有哪些?

    樹莓派4 性能大比拼:標準Linux與實時Linux 4.19內(nèi)核的延遲測試

    引言本文是對我之前關(guān)于RaspberryPi3同一主題的帖子的更新。與之前的帖子一樣,我使用的是隨Raspbian鏡像提供的標準內(nèi)核,以及應(yīng)用了RT補丁的相似內(nèi)核版本。對于實時版,我
    的頭像 發(fā)表于 03-25 09:39 ?844次閱讀
    樹莓派4 <b class='flag-5'>性能</b>大比拼:標準<b class='flag-5'>Linux</b>與實時<b class='flag-5'>Linux</b> 4.19<b class='flag-5'>內(nèi)核</b>的延遲測試