alsa 测试 linux_Linux低延迟服务器系统调优
最近做了一些系統(tǒng)和網(wǎng)絡(luò)調(diào)優(yōu)相關(guān)的測試,達(dá)到了期望的效果,有些感悟。同時(shí),我也發(fā)現(xiàn)知乎上對(duì)Linux服務(wù)器低延遲技術(shù)的討論比較欠缺(滿嘴高并發(fā)現(xiàn)象);或者對(duì)現(xiàn)今cpu + 網(wǎng)卡的低延遲潛力認(rèn)識(shí)不足(動(dòng)輒FPGA現(xiàn)象),比如一篇知乎高贊的介紹FPGA的文章寫到“從延遲上講,網(wǎng)卡把數(shù)據(jù)包收到 CPU,CPU 再發(fā)給網(wǎng)卡,即使使用 DPDK 這樣高性能的數(shù)據(jù)包處理框架,延遲也有 4~5 微秒。更嚴(yán)重的問題是,通用 CPU 的延遲不夠穩(wěn)定。例如當(dāng)負(fù)載較高時(shí),轉(zhuǎn)發(fā)延遲可能升到幾十微秒甚至更高”,剛好我前幾天做過類似的性能測試,發(fā)現(xiàn)一個(gè)tcp或udp的echo server可以把網(wǎng)卡到網(wǎng)卡的延遲穩(wěn)定在1微秒以內(nèi),不會(huì)比FPGA方案慢很多吧?
因此,我覺得有必要分享下自己的見解。總的來說,我打算分兩篇文章討論相關(guān)低延遲技術(shù):
1)系統(tǒng)調(diào)優(yōu)(本文):一些低延遲相關(guān)的Linux系統(tǒng)設(shè)置,和一些原則。
2)網(wǎng)絡(luò)調(diào)優(yōu):使用solarflare網(wǎng)卡降低網(wǎng)絡(luò)IO延遲。
這里不打算介紹用戶空間的延遲優(yōu)化,因?yàn)樘珡V泛了,另外我之前的文章也分享一些解決某類問題的低延遲類庫。
說到低延遲,關(guān)鍵點(diǎn)不在低,而在穩(wěn)定,穩(wěn)定即可預(yù)期,可掌控,其對(duì)于諸如高頻交易領(lǐng)域來說尤為重要。而說到Linux的低延遲技術(shù),一個(gè)不能不提的詞是"kernel bypass",也就是繞過內(nèi)核,為什么呢?因?yàn)閮?nèi)核處理不僅慢而且延遲不穩(wěn)定。可以把操作系統(tǒng)想象成一個(gè)龐大的框架,它和其他軟件框架并沒有什么本質(zhì)的不同,只不過更加底層更加復(fù)雜而已。既然是框架,就要考慮到通用性,需要滿足各種對(duì)類型用戶的需求,有時(shí)你只需要20%的功能,卻只能take all。
因此我認(rèn)為一個(gè)延遲要求很高(比如個(gè)位數(shù)微秒級(jí)延遲)的實(shí)時(shí)任務(wù)是不能觸碰內(nèi)核的,(當(dāng)然在程序的啟動(dòng)初始化和停止階段沒有個(gè)要求,That's how linux works)。這里的避免觸碰是一個(gè)比bypass更高的要求:不能以任何方式進(jìn)入內(nèi)核,不能直接或間接的執(zhí)行系統(tǒng)調(diào)用(trap),不能出現(xiàn)page fault(exception),不能被中斷(interrupt)。trap和exception是主動(dòng)進(jìn)入內(nèi)核的方式,可以在用戶程序中避免,這里不深入討論(比如在程序初始化階段分配好所有需要的內(nèi)存并keep的物理內(nèi)存中;讓其他非實(shí)時(shí)線程寫日志文件等)。本文的關(guān)鍵點(diǎn)在于避免關(guān)鍵線程被中斷,這是個(gè)比較難達(dá)到的要求,但是gain卻不小,因?yàn)樗茄舆t穩(wěn)定的關(guān)鍵點(diǎn)。即使中斷發(fā)生時(shí)線程是空閑的,但重新回到用戶態(tài)后cpu緩存被污染了,下一次處理請求的延遲也會(huì)變得不穩(wěn)定。
不幸的是Linux并沒有提供一個(gè)簡單的選項(xiàng)讓用戶完全關(guān)閉中斷,也不可能這么做(That's how linux works),我們只能想法設(shè)法避免讓關(guān)鍵任務(wù)收到中斷。我們知道,中斷是cpu core收到的,我們可以讓關(guān)鍵線程綁定在某個(gè)core上,然后避免各種中斷源(IRQ)向這個(gè)core發(fā)送中斷。綁定可以通過taskset或 sched_setaffinity實(shí)現(xiàn),這里不贅述。避免IRQ向某個(gè)core發(fā)中斷可以通過改寫/proc/irq/*/smp_affinity來實(shí)現(xiàn)。例如整個(gè)系統(tǒng)有一塊cpu共8個(gè)核,我們想對(duì)core 4~7屏蔽中斷,只需把非屏蔽中斷的core(0 ~ 3)的mask "f"寫入smp_affinity文件。這個(gè)操作對(duì)硬件中斷(比如硬盤和網(wǎng)卡)都是有效的,但對(duì)軟中斷無效(比如local timer interrupt和work queue),對(duì)于work queue的屏蔽可以通過改寫/sys/devices/virtual/workqueue/*/cpumask來實(shí)現(xiàn),本例中還是寫入"f"。
那么剩下的主要就是local timer interrupt(LOC in /proc/interrupts)了。Linux的scheduler time slice是通過LOC實(shí)現(xiàn)的,如果我們讓線程獨(dú)占一個(gè)core,就不需要scheduler在這個(gè)core上切換線程了,這是可以做到的:通過isolcpus系統(tǒng)啟動(dòng)選項(xiàng)隔離一些核,讓它們只能被綁定的線程使用,同時(shí),為了減少獨(dú)占線程收到的LOC頻率,我們還需要使用"adaptive-ticks"模式,這可以通過nohz_full和rcu_nocbs啟動(dòng)選項(xiàng)實(shí)現(xiàn)。本例中需要在系統(tǒng)啟動(dòng)選項(xiàng)加入isolcpus=4,5,6,7 nohz_full=4,5,6,7 rcu_nocbs=4,5,6,7 來使得4~7核變成adaptive-ticks。adaptive-ticks的效果是:如果core上的running task只有一個(gè)時(shí),系統(tǒng)向其發(fā)送LOC的頻率會(huì)降低成每秒一次,內(nèi)核文檔解釋了不能完全屏蔽LOC的原因:"Some process-handling operations still require the occasional scheduling-clock tick. These operations include calculating CPU load, maintaining sched average, computing CFS entity vruntime, computing avenrun, and carrying out load balancing. They are currently accommodated by scheduling-clock tick every second or so. On-going work will eliminate the need even for these infrequent scheduling-clock ticks."。
至此,通過修改系統(tǒng)設(shè)置,我們能夠把中斷頻率降低成每秒一次,這已經(jīng)不錯(cuò)了。如果想做的更完美些,讓關(guān)鍵線程長時(shí)間(比如幾個(gè)小時(shí))不收到任何中斷,只能修改內(nèi)核延長中斷的發(fā)送周期。不同kernel版本相關(guān)代碼有所差異,這里就不深入討論。不過大家可能會(huì)顧慮:這樣改變系統(tǒng)運(yùn)行方式會(huì)不會(huì)導(dǎo)致什么問題呢?我的經(jīng)驗(yàn)是,這有可能會(huì)影響某些功能的正常運(yùn)轉(zhuǎn)(如內(nèi)核文檔提到的那些),但我尚未發(fā)現(xiàn)程序和系統(tǒng)發(fā)生任何異常,說明這項(xiàng)內(nèi)核修改至少不會(huì)影響我需要的功能,我會(huì)繼續(xù)使用。
兩個(gè)原則:
1)如果一件事情可以被delay一段時(shí)間,那它往往能夠被delay的更久,因?yàn)樗鼪]那么重要。
2)不要為不使用的東西付費(fèi),對(duì)于性能優(yōu)化來說尤為如此。
如何檢測中斷屏蔽的效果呢?可以watch/proc/interrupts文件的變化 。更好的方法是用簡單的測試程序來驗(yàn)證延遲的穩(wěn)定性:
#includeuint64_t now() {
return __builtin_ia32_rdtsc();
}
int main() {
uint64_t last = now();
while (true) {
uint64_t cur = now();
uint64_t diff = cur - last;
if (diff > 300) {
std::cout << "latency: " << diff << " cycles" << std::endl;
cur = now();
}
last = cur;
}
return 0;
}
通過taskset綁定一個(gè)核運(yùn)行程序,每進(jìn)入一次內(nèi)核會(huì)打印一條信息。
最后,除了進(jìn)入內(nèi)核以外,影響延遲穩(wěn)定性的因素還有cache miss和tlb miss。
對(duì)于減少cache miss,一方面需要優(yōu)化程序,minimize memory footprint,或者說減少一個(gè)操作訪問cache line的個(gè)數(shù),一個(gè)緩存友好例子是一種能高速查找的自適應(yīng)哈希表文章中的哈希表的實(shí)現(xiàn)方式。另一方面,可以通過分(lang)配(fei)硬件資源讓關(guān)鍵線程占有更多的緩存,比如系統(tǒng)有兩塊CPU,每塊8核,我們可以把第二塊CPU的所有核都隔離掉,然后把關(guān)鍵線程綁定到其中的部分核上,可能系統(tǒng)只有一兩個(gè)關(guān)鍵線程,但它們卻能擁有整塊CPU的L3 cache。
對(duì)于減少tlb miss,可以使用huge pages。
圖片和內(nèi)容源自網(wǎng)絡(luò)分享,若有侵權(quán),請聯(lián)系刪除!
上海艾磊科技有限公司專門為企業(yè)提供IT咨詢,IT外包,系統(tǒng)集成,以及各類IT增值服務(wù)。其中增值服務(wù)包括OFFICE 365云服務(wù),鼎捷企業(yè)ERP管理軟件,云備份,企業(yè)郵箱,無線覆蓋,上網(wǎng)行為管理,VPN架設(shè),網(wǎng)絡(luò)安全服務(wù),INTERNET接入,設(shè)備租賃, IP電話服務(wù)總結(jié)
以上是生活随笔為你收集整理的alsa 测试 linux_Linux低延迟服务器系统调优的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: codeblock 带mingw的版本_
- 下一篇: 苹果电脑怎么设置佳博标签打印机_热销斑马