日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

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內(nèi)核性能剖析的方法學(xué)和主要工具

Linux閱碼場(chǎng) ? 來(lái)源:Linux閱碼場(chǎng) ? 作者:Linux閱碼場(chǎng) ? 2022-12-07 15:27 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

計(jì)算機(jī)科學(xué)的先驅(qū)Donald Knuth(高德納)曾經(jīng)說(shuō)過(guò):“過(guò)早的優(yōu)化是萬(wàn)惡之源”,更詳細(xì)的原文如下:“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.”它向我們揭示了一個(gè)道理,我們應(yīng)該首先定位到那3%真正成為瓶頸的代碼,而忽略97%那些“small efficiencies”,所謂“將軍趕路,不打小鬼”,這是我們進(jìn)行一切性能優(yōu)化的前提。因此,剖析(profiling),成為了性能優(yōu)化中最重要的環(huán)節(jié)之一。

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

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

一、性能剖析的總體認(rèn)識(shí)

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

吞吐

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

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

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

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

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

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

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

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

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

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

case A原子操作的次數(shù)不會(huì)是case B的10倍,它實(shí)際遠(yuǎn)小于10倍,比如實(shí)測(cè)結(jié)果可能是嚇?biāo)滥愕?倍(當(dāng)然每個(gè)具體的SoC都可能不一樣),等于10倍的硬件目前這個(gè)世界還沒(méi)有做出來(lái),未來(lái)也造不出來(lái)。

這些σ系數(shù)、k系數(shù)對(duì)服務(wù)器的影響,遠(yuǎn)大于對(duì)桌面和手機(jī)等系統(tǒng),因?yàn)榉?wù)器上的p特別大。所以,長(zhǎng)期困擾服務(wù)器的問(wèn)題,比如我從50個(gè)cpu變成100個(gè)cpu,MySQL的吞吐一定增加了一倍了嗎?不好意思,很可能只是嚇?biāo)滥愕?.3倍,如果運(yùn)氣不好的話,還可能倒退。

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

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

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

延遲

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

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

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

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

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

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

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

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

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

延遲的幾個(gè)主要可能的來(lái)源:

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

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

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

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

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

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

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

功耗

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

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

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

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

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

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

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

所以從性能分析的角度來(lái)說(shuō),我們也要把這些紅框部分挖掘出來(lái)進(jìn)行分析優(yōu)化,因?yàn)楸举|(zhì)他們也是純耗電,屬于overhead而不是real work。

90分到100分特別難

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

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

努力到一定程度后,有沒(méi)有可能越努力成績(jī)?cè)讲钅??我覺(jué)得是可能的,因?yàn)閁niversal Scalability law(USL),學(xué)麻了容易走火入魔,反而出現(xiàn)性能的collapse。

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


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

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

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

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

二、on-cpu分析

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

on-cpu火焰圖

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

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

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

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

我們得到如下火焰圖:

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

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

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

CPU消耗比例分布

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

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

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

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

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

最后一公里

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

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

從annotate的結(jié)果可以看出,至少,在筆者運(yùn)行的qemu平臺(tái)上,tlbi附近的開(kāi)銷是非常大的,其他的代碼開(kāi)銷幾乎可以忽略不計(jì)。當(dāng)然,真實(shí)的ARM64硬件上,tlbi也絕對(duì)不便宜。

中斷屏蔽的問(wèn)題

在一個(gè)類似如下spin_lock_irqsave()、spin_unlock_irqrestore()的區(qū)間里,由于采樣的中斷都是被屏蔽的,所以中間perf的采樣結(jié)果,都會(huì)在spin_unlock_irqrestore()開(kāi)啟中斷的這一刻爆出來(lái),導(dǎo)致ARM64平臺(tái)下,采樣的熱點(diǎn)落在類似spin_unlock_irqrestore()這樣的地方。這是不準(zhǔn)確的。

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

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

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

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

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

這個(gè)時(shí)候,你不開(kāi)啟irqchip.gicv3_pseudo_nmi=1是不可能perf annonate出來(lái)這個(gè)函數(shù)哪句話是熱點(diǎn)的,所有熱點(diǎn)都會(huì)落在末尾的local_irq_restore()這句話。但是開(kāi)啟后,你才會(huì)抓到真正的熱點(diǎn):

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

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

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

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

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

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

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

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

比如運(yùn)行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》中,革命性地給出了一個(gè)從CPU指令執(zhí)行的順暢程度來(lái)評(píng)估和發(fā)現(xiàn)瓶頸的方法,允許我們從黑盒的角度以諸葛孔明“隆中對(duì)”式的格局來(lái)看問(wèn)題。

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

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

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

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

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

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

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

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

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

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

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

Intel處理器架構(gòu)下,已經(jīng)將top-down完全地工具化,有專門的top-down工具,有的甚至已經(jīng)圖形化了,比如VTune Profiler里面就有類似功能【4】,可以具體化到每一個(gè)特定函數(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高達(dá)3.589,主要是它的Back-End Bound嚴(yán)重,其中Memory Bound高達(dá)73.2%,所以優(yōu)化這個(gè)函數(shù),要多從cache命中率(L1,L2,L3)、DDR帶寬/延遲角度考慮。而優(yōu)化sort_basket()函數(shù)則要多從分支預(yù)測(cè)優(yōu)化角度考慮,因?yàn)樗腂ad Speculation高達(dá)50.4%。

有的童鞋對(duì)Bad Speculation可能還是不太明白,下面我們通過(guò)一個(gè)代碼栗子:

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

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

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

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

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

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

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

此時(shí)的IPC也很大,達(dá)到3.49,比較接近4.0了:

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

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

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

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

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

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

我們現(xiàn)在覺(jué)得memory bound是上述場(chǎng)景下kswapd的大頭,我們實(shí)際也可以采樣下kswapd的cache-misses。簡(jiǎn)單運(yùn)行“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的平臺(tái)享受上面的工具化優(yōu)勢(shì)。其他平臺(tái)的童鞋也不必懊惱,perf本身也具有topdown能力,perf stat后面有個(gè)參數(shù)是--topdown:

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

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

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

整個(gè)on-cpu分析的過(guò)程是top-down的,過(guò)程中的某些步驟也是topdown的,我們用一個(gè)流程圖來(lái)描述:

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

三、off-cpu分析

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

直方圖

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

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

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

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

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

我們?cè)趇nclude/trace/events/vmscan.h和mm/vmscan.c中增加這個(gè)trace:

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

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

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

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

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

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

從直方圖可看出,實(shí)驗(yàn)場(chǎng)景中,回收到32個(gè)pages的機(jī)會(huì)最多,占據(jù)76598次,其次是回收到1個(gè)、0個(gè)和2個(gè)的。

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

復(fù)原:

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

開(kāi)啟新的采樣:

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

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

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

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

trace_xxx_sys_yyy_latency(latency/5000, 1);

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

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

eBPF/BCC中本身內(nèi)嵌多個(gè)直方圖工具,可滿足許多常見(jiàn)的生活必須,比如之前演示的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這個(gè)筆者也經(jīng)常用,比如看一下vfs_read()這個(gè)函數(shù)的執(zhí)行時(shí)間分布,只需要把函數(shù)名加在funclatency之后就好:

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

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

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

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

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

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

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

off-cpu火焰圖

實(shí)際上,eBPF/BCC的代碼倉(cāng)庫(kù)已經(jīng)寫(xiě)好了off-cpu工具,可以直接拿來(lái)用:

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

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

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

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

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

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

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

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

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

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

# CONFIG_PREEMPT_NONE is not set

CONFIG_PREEMPT_VOLUNTARY=y

# CONFIG_PREEMPT is not set

測(cè)試的環(huán)境開(kāi)啟了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個(gè)方面原因:

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

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

時(shí)間片到期后, timer中斷進(jìn)來(lái),把它切換走。

我們把這3個(gè)塊分別畫(huà)3個(gè)圓圈:

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

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

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

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

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

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

繪制出來(lái)的kswapd的off-cpu火焰圖如下:

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

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

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

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

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

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

得到的圖如下:

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

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

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

Lock Contention分析

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

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

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

然后生成報(bào)告:

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

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

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

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

四、總結(jié)

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

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

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

審核編輯 :李倩

聲明:本文內(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

    文章

    11332

    瀏覽量

    226005
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11822

    瀏覽量

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

    關(guān)注

    0

    文章

    171

    瀏覽量

    14925

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

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

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

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

    Linux Kernel 6.1 tools目錄全解析?| RK平臺(tái)ARM64交叉編譯實(shí)戰(zhàn)指南

    ? 在瑞芯微( RK ) ARM64 平臺(tái)嵌入式 Linux 開(kāi)發(fā)、內(nèi)核調(diào)試與硬件外設(shè)測(cè)試中, Linux 內(nèi)核源碼自帶的 tools 目錄 是官方標(biāo)配的
    的頭像 發(fā)表于 04-16 18:42 ?7637次閱讀
    <b class='flag-5'>Linux</b> Kernel 6.1 tools目錄全解析?| RK平臺(tái)ARM64交叉編譯實(shí)戰(zhàn)指南

    如何理解Linux內(nèi)核中的PCIe驅(qū)動(dòng)

    我們習(xí)慣了用 Verilog 去死磕 PCIe 的底層協(xié)議狀態(tài)機(jī)。但一旦越過(guò)硬件邊界來(lái)到操作系統(tǒng)層面,Linux 內(nèi)核是如何接管并驅(qū)動(dòng)這些 PCI/PCIe 設(shè)備的呢?由于不同的 CPU 架構(gòu)實(shí)現(xiàn)了
    的頭像 發(fā)表于 04-11 17:22 ?1292次閱讀

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

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

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

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

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

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

    深入RK3588內(nèi)核:rockchip_linux_defconfig的作用與調(diào)試價(jià)值

    在 RK3588 芯片的 Linux 開(kāi)發(fā)中,有一個(gè)文件始終是開(kāi)發(fā)者繞不開(kāi)的核心 ——kernel/arch/arm64/configs/rockchip_linux_defconfig。無(wú)論是首次
    的頭像 發(fā)表于 02-03 15:56 ?1399次閱讀
    深入RK3588<b class='flag-5'>內(nèi)核</b>:rockchip_<b class='flag-5'>linux</b>_defconfig的作用與調(diào)試價(jià)值

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

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

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

    今天給大家分享一個(gè)linux內(nèi)核自帶的調(diào)試工具,該工具可用于查看和定位系統(tǒng)問(wèn)題,進(jìn)程運(yùn)行過(guò)程探索,進(jìn)行進(jìn)程監(jiān)控,對(duì)每個(gè)系統(tǒng)調(diào)用都可以監(jiān)測(cè),有助于我們優(yōu)化系統(tǒng)
    的頭像 發(fā)表于 01-30 17:03 ?2054次閱讀
    <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)實(shí)戰(zhàn)指南

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

    Linux-RT特點(diǎn)及簡(jiǎn)單應(yīng)用

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

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

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

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

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

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

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

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

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

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

    Linux系統(tǒng)運(yùn)維和性能優(yōu)化中,內(nèi)核參數(shù)(sysctl)的配置至關(guān)重要。合理的參數(shù)調(diào)整可以顯著提升網(wǎng)絡(luò)性能、系統(tǒng)穩(wěn)定性及資源利用率。然而,僅僅修改參數(shù)是不夠的,如何驗(yàn)證這些參數(shù)是否生
    的頭像 發(fā)表于 05-29 17:40 ?1404次閱讀
    微山县| 五家渠市| 江都市| 安阳县| 平凉市| 托克逊县| 兴山县| 玉林市| 阳谷县| 连城县| 陵水| 苍山县| 栾川县| 临夏县| 赤壁市| 太原市| 千阳县| 繁峙县| 鹤峰县| 昔阳县| 高唐县| 习水县| 固镇县| 宁乡县| 都江堰市| 印江| 通化市| 泰宁县| 康马县| 山丹县| 微博| 普兰店市| 剑阁县| 平昌县| 夏邑县| 凤城市| 巴塘县| 河间市| 南木林县| 温州市| 南汇区|