首先前计,要對軟中斷有一個認(rèn)識潜秋,程序運(yùn)行后,操作系統(tǒng)會發(fā)送程序需要的一些cpu指令到某個cpu疾捍,扔給CPU的這個過程是異步的,cpu獲得指令后操作完成會觸發(fā)一個硬中斷栏妖,并且把操作的結(jié)果保存在寄存器乱豆,之后linux內(nèi)核會啟動ksofttrip進(jìn)程去,來獲取操作結(jié)果吊趾,這個動作就叫做軟中斷宛裕。
linux默認(rèn)會起n個ksofttrip進(jìn)程瑟啃,n等于cpu的個數(shù),ksofttrip是死循環(huán)揩尸,只要有軟中斷蛹屿,它就會一直去獲取,n個ksoftrip獲取源是一樣的岩榆,為什么要起n個進(jìn)程呢错负?就是為了 ,當(dāng)某個cpu空閑勇边,哪個就去跑犹撒。通常操作系統(tǒng)里它的進(jìn)程名是 ksoftrip/n ,n是對應(yīng)的cpu的編號,ksoft進(jìn)程跟cpu是一對一綁定的粒褒。
現(xiàn)在來說說網(wǎng)卡的性能問題识颊,要想優(yōu)化,首先你的網(wǎng)卡必須是多通道隊列的奕坟。那如何知道你的網(wǎng)卡是否是多隊列的呢祥款? 通過cat /proc/interrept |grep eth0|wc -l 可以看到網(wǎng)卡通道隊列的數(shù)量.
現(xiàn)在來來說說優(yōu)化方案,為什么要優(yōu)化月杉,因為linux默認(rèn)情況所有的網(wǎng)卡的軟中斷都是的cpu0刃跛,所以加入你的ksoftrip/0總是跑滿,就說明可能是網(wǎng)卡問題了。
方案1 沙合,SMP IRQ affinity技術(shù)
說白了奠伪,就是信號量分布技術(shù),把特定信號量的處理放到固定的cpu上首懈,每個網(wǎng)卡的通道隊列都有一個自己的信號量绊率。
首先查看所有網(wǎng)卡通道隊列的信號量,方法 cat/proc/interrept |grep eth0
每行最開頭的數(shù)字“n:”就是信號量究履,在/proc/irq/下面可以找到對應(yīng)的以信號量命名的目錄
找完了之后滤否,可以進(jìn)行信號量綁定了,在/proc/irq/n/下面有兩個文件最仑,分別是smp_affinity跟smp_affinity_list, 這兩個是文件的內(nèi)容是對應(yīng)的藐俺,smp_affinity里是通過bitmask算法綁定cpu,smp_affinity_list是通過數(shù)字指定cpu編號的方法泥彤,例如 cpu0欲芹,文件里就是“0”,如果是cpu1跟2就是“1,2”
!吟吝!重點(diǎn)來了菱父,雖然默認(rèn)里面填寫的是多個,但是!U阋恕官辽!但是它只跑在綁定cpu中的第一個!K谒病同仆!坑啊H蛊贰K着!
所以清酥,你要做的就是單獨(dú)綁定每一個網(wǎng)卡的通道隊列扶镀。
直接echo "1" >/proc/irq/(cpu1的信號量)/snmp_affinity_list
echo "3" >/proc/irq/$(cpu2的信號量)/snmp_affinity_list
這個是最快速的解決方案,提升效率顯著把媲帷3艟酢!辱志!
升級方案2蝠筑,在方案1基礎(chǔ)之上,RPS/RFS技術(shù)
此技術(shù)大家可以查網(wǎng)上揩懒,文章很多什乙,優(yōu)化效果是,單個網(wǎng)卡通道隊列的軟中斷會平均到所有cpu上已球,并且會優(yōu)化為臣镣,中斷落在發(fā)出中斷的程序所在的那個cpu上,這樣節(jié)省了cpu cache智亮。
壞消息是對單隊列網(wǎng)卡而言忆某,「smp_affinity」和「smp_affinity_list」配置多CPU無效。
好消息是Linux支持RPS阔蛉,通俗點(diǎn)來說就是在軟件層面模擬實現(xiàn)硬件的多隊列網(wǎng)卡功能弃舒。
首先看看如何配置RPS,如果CPU個數(shù)是 8 個的話状原,可以設(shè)置成 ff:
shell> echo ff > /sys/class/net/eth0/queues/rx-0/rps_cpus
接著配置內(nèi)核參數(shù)rps_sock_flow_entries(官方文檔推薦設(shè)置: 32768):
shell> sysctl net.core.rps_sock_flow_entries=32768
最后配置rps_flow_cnt聋呢,單隊列網(wǎng)卡的話設(shè)置成rps_sock_flow_entries即可:
echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
說明:如果是多隊列網(wǎng)卡,那么就按照隊列數(shù)量設(shè)置成 rps_sock_flow_entries / N 颠区。