宋洪治 武杰 張杰 孔陽 馬毅超
1(中國科學(xué)技術(shù)大學(xué)物理系 合肥 230026)
2(中國科學(xué)技術(shù)大學(xué)近代物理系 合肥 230026)
作為一種通用可靠的網(wǎng)絡(luò)傳輸技術(shù),以太網(wǎng)技術(shù)幾乎存在于所有實驗中[1],很多實驗采用以太網(wǎng)將讀出電子學(xué)模塊的數(shù)據(jù)傳送到更高級別系統(tǒng)[2–5]。為完成網(wǎng)絡(luò)數(shù)據(jù)傳輸任務(wù),一般需操作系統(tǒng)的支持,采用的操作系統(tǒng)主要有 VxWorks[3]和 Linux[2,6]。其中,Linux系統(tǒng)開源低成本,為研究者所熟知,且有成熟穩(wěn)定的網(wǎng)絡(luò)協(xié)議棧,非常適合網(wǎng)絡(luò)通信。
本文基于ARM處理器用Linux 2.4內(nèi)核構(gòu)建了用于數(shù)據(jù)傳輸?shù)那度胧较到y(tǒng)。結(jié)合具體數(shù)據(jù)分析了系統(tǒng)數(shù)據(jù)接收過程,給出系統(tǒng)性能變化的原因及優(yōu)化的方向。
系統(tǒng)以ARM處理器為核心,使用以太網(wǎng)傳輸數(shù)據(jù)。為保證數(shù)據(jù)傳輸?shù)目煽啃裕W(wǎng)絡(luò)傳輸使用TCP/IP協(xié)議。在不考慮EMAC(Ethernet MAC)和物理層操作情況下,用TCP發(fā)送數(shù)據(jù)消耗的處理器周期為接收數(shù)據(jù)的~4/5[7]。為測試系統(tǒng)在更大壓力下的表現(xiàn),采用TCP接收數(shù)據(jù)的方式。
系統(tǒng)接收數(shù)據(jù)包過程[8–11]如圖1。網(wǎng)絡(luò)質(zhì)量很好而大量接收數(shù)據(jù)時,可忽略失序的TCP報文。
圖1 Linux網(wǎng)絡(luò)子系統(tǒng)TCP協(xié)議收包過程Fig.1 The packet receiving process of Linux networking subsystem for TCP.
Linux網(wǎng)絡(luò)子系統(tǒng)通過軟中斷[8,9]機制處理接收的數(shù)據(jù)包。鏈路層收到的數(shù)據(jù)幀由 EMAC通過DMA(Direct Memory Access)操作復(fù)制到環(huán)形緩存。環(huán)形緩存由多個能容納最大鏈路幀長的接收緩存構(gòu)成。一個接收緩存有“準備”和“使用”兩種狀態(tài)。EMAC只可向“準備”態(tài)的接收緩存復(fù)制數(shù)據(jù)幀;處于“使用”態(tài)的接收緩存只有被網(wǎng)絡(luò)驅(qū)動讀取,并重置為“準備”態(tài)后才能重新被EMAC使用。通常TCP數(shù)據(jù)包接收分為如下三階段。
1.2.1 以太網(wǎng)數(shù)據(jù)幀通過物理層到達MAC層
此時,EMAC自動檢查數(shù)據(jù)幀的前導(dǎo)、目的物理地址和循環(huán)冗余校驗(CRC),并啟動DMA操作將其復(fù)制到一個處“準備”態(tài)的接收緩存中。如數(shù)據(jù)幀有效,EMAC會將該接收緩存置為“使用”態(tài),并產(chǎn)生收到數(shù)據(jù)幀的中斷。網(wǎng)絡(luò)驅(qū)動響應(yīng)這個中斷并做如下操作:(1) 分配 sk_buff[8,9,12]對象;(2) 復(fù)制接收緩存中內(nèi)容到sk_buff對象;(3) 根據(jù)數(shù)據(jù)幀封裝協(xié)議更新sk_buff對象中的控制信息;(4) 將sk_buff對象添加到當前處理器的接收隊列中;(5) 產(chǎn)生軟中斷通知協(xié)議棧新數(shù)據(jù)幀的到來;(6) 重置接收緩存為“準備”態(tài)。為避免中斷響應(yīng)不及時,設(shè)備驅(qū)動在每次收到中斷時對所有處于“使用”態(tài)的接收緩存使用上述操作。如果沒有可用接收緩存,EMAC將丟棄收到的幀。同樣,在EMAC成功接收數(shù)據(jù)幀,但分配 sk_buff失敗情況下,設(shè)備驅(qū)動也會丟棄對應(yīng)的幀。TCP連接有流量控制[13]機制,所以通常不出現(xiàn)分配 sk_buff失敗的情況。出于效率的考慮,一個 sk_buff對象包含足夠大空間來容納協(xié)議棧中每一層添加的控制信息,且一直處于內(nèi)存中同一位置,從而避免了數(shù)據(jù)的跨層復(fù)制操作。
1.2.2 協(xié)議棧響應(yīng)軟中斷,在系統(tǒng)的中斷上下文中處理收到的數(shù)據(jù)幀
網(wǎng)絡(luò)層的IP協(xié)議處理完數(shù)據(jù)幀后,將數(shù)據(jù)包送到傳輸層交給TCP協(xié)議處理。Linux 2.4的TCP用預(yù)收隊列、接收隊列、候補隊列或失序隊列處理收到的數(shù)據(jù)包。這里數(shù)據(jù)包有三種可能的傳輸路徑:
(1) 如果軟中斷發(fā)生時,進程正在內(nèi)核空間中操作隊列接收數(shù)據(jù),則數(shù)據(jù)包會被放到候補隊列中等待進程進一步處理。
(最新消息:經(jīng)過作者修訂的第四版《養(yǎng)生三記》,增補了很多精彩篇章,新版已由黑龍江科技出版社出版發(fā)行,各地新華書店將陸續(xù)到貨。辦理郵購的地點為:哈爾濱市南崗區(qū)人和街93號,收款人:彭祖補品屋。勿寄私人,以免延誤。書價40元,免收郵費。免費聯(lián)系電話:400-609-2883,匯款單附言請寫明您的詳細地址和電話,以便給您寄書。)
(2) 如果此時接收數(shù)據(jù)的進程正因為等待期望的數(shù)據(jù)而睡眠,數(shù)據(jù)包會被放到進程的預(yù)收隊列中。預(yù)收隊列主要為實現(xiàn)計算校驗和并復(fù)制到用戶空間的操作[14],以節(jié)省CPU周期。預(yù)收隊列無溢出時,其中的數(shù)據(jù)包在進程上下文中處理。若送到預(yù)收隊列中的sk_buff對象的總緩存長度超過TCP協(xié)議棧預(yù)先設(shè)定的接收緩存大小,系統(tǒng)判定預(yù)收隊列溢出。此時,預(yù)收隊列中的數(shù)據(jù)包將在中斷上下文中處理。
如滿足快速路徑條件:TCP包沒有失序、當前進程正是讀取當前套接字的進程、應(yīng)用程序提供足夠大用戶空間接收緩存能容納當前 TCP數(shù)據(jù)包所有數(shù)據(jù),則數(shù)據(jù)包將通過快速路徑,以計算校驗和并復(fù)制的方式直接到達用戶緩存。否則TCP數(shù)據(jù)包將通過慢速路徑。
慢速路徑中,未失序TCP包經(jīng)處理后被發(fā)送到接收隊列,失序者則送到失序隊列。若能大量連續(xù)地接收數(shù)據(jù),則認為網(wǎng)絡(luò)條件很好,可忽略TCP數(shù)據(jù)包失序,故圖1未給出失序時的數(shù)據(jù)傳輸路徑。
(3) 如在軟中斷時,進程既不在操作隊列,也不在等待網(wǎng)絡(luò)數(shù)據(jù),說明進程此時正運行或休眠在與網(wǎng)絡(luò)接收無關(guān)的地方。此時,收到的數(shù)據(jù)包會依據(jù)快速路徑條件通過快速或慢速路徑。
1.2.3 用戶進程通過系統(tǒng)調(diào)用在進程上下文中處理接收到的數(shù)據(jù)
進程上下文中,將按先預(yù)收隊列、再接收隊列、最后候補隊列的優(yōu)先次序處理數(shù)據(jù)。接收隊列中數(shù)據(jù)被直接復(fù)制到用戶空間接收緩存。與軟中斷中預(yù)收隊列溢出時數(shù)據(jù)的流向類似,預(yù)收和候補隊列中的數(shù)據(jù)將通過快速或慢速路徑到達用戶空間或接收隊列。與軟中斷中情況不同的是,慢速路徑中如滿足當前進程是接收當前數(shù)據(jù)包的進程,當前數(shù)據(jù)包序號是期望的序號,且有足夠的用戶空間接收緩存,則數(shù)據(jù)被復(fù)制到用戶空間,而非接收隊列中。
為測量系統(tǒng)用 TCP/IP協(xié)議從以太網(wǎng)接收數(shù)據(jù)時各部分消耗的處理器時間,用AT91RM9200三個定時計數(shù)器級聯(lián)成一個運行在30 MHz頻率下的48位計數(shù)器,統(tǒng)計內(nèi)核相關(guān)部分的運行時間。
根據(jù)Linux 2.4內(nèi)核TCP/IP協(xié)議棧結(jié)構(gòu)特點,將計時區(qū)段劃分為:(1) 不在中斷響應(yīng)中運行的驅(qū)動程序時間,(2) 中斷響應(yīng)中運行的驅(qū)動程序時間,(3) 軟中斷中運行的協(xié)議棧發(fā)送數(shù)據(jù)代碼的運行時間,(4) 軟中斷中運行的協(xié)議棧接收數(shù)據(jù)代碼的運行時間,(5) 不在軟中斷中運行的協(xié)議棧接收數(shù)據(jù)代碼的運行時間,(6) 不在軟中斷中運行的發(fā)送數(shù)據(jù)代碼的運行時間,(7) TCP重傳定時器運行時間,(8) TCP延遲確認定時器運行時間,(9) TCP保活定時器運行時間,(10) 總運行時間。
根據(jù)測得各個時間的值,得到網(wǎng)絡(luò)驅(qū)動程序及TCP/IP協(xié)議棧的運行時間和系統(tǒng)其它部分運行所需時間:
除測量協(xié)議棧消耗時間外,還記錄了TCP接收相關(guān)的其它信息。
測試時,數(shù)據(jù)從PC送出,直接到達目標板。測試條件為:網(wǎng)絡(luò)用TCP連接,發(fā)送方發(fā)送256 MB數(shù)據(jù),接收方用64 KB協(xié)議棧接收緩存,用recv系統(tǒng)調(diào)用配合 MSG_WAITALL選項使用不同用戶緩存接收數(shù)據(jù)。
圖2是有無使用性能測試代碼時不同用戶空間接收緩存下系統(tǒng)接收數(shù)據(jù)的速率。
圖2 不同用戶空間接收緩存下的接收速率Fig.2 Rx throughput with various Rx buffer in user space.
系統(tǒng)接收數(shù)據(jù)時,無論何種情況,處理器使用率都一直處于100%。由圖2,接收速率隨用戶空間緩存增大而增大。沒用測試代碼、用戶空間緩存達64 K字節(jié)時,系統(tǒng)的接收速率飽和。即對200 MHz的 ARM9處理器能力,如其配置和 AT91RM9200相當,想要充分發(fā)揮百兆以太網(wǎng)數(shù)據(jù)傳輸速度,至少需開辟64 K字節(jié)用戶空間緩存。使用性能測試代碼、用戶空間緩存4 M字節(jié)時,接收速率飽和。
圖3是不同用戶空間接收緩存下各計時區(qū)段占用的時間。對當前測試,目標板不發(fā)送數(shù)據(jù),則重傳定時器不運行。由于目標板連續(xù)接收數(shù)據(jù),延時確認定時器超時前就被重置。而且并沒使能?;疃〞r器(Keep-alive timer),故圖3未給出這三個運行時間為零的定時器的運行時間數(shù)據(jù)。
圖3 不同用戶空間接收緩存下TCP處理的時間分布Fig.3 TCP processing time distribution with various Rx buffer in user space.
表1給出與TCP接收相關(guān)的其它一些測量值。在進程上下文即將處理接收隊列前,接收隊列中sk_buff對象的數(shù)目被累加。將累加的結(jié)果與接收隊列的處理次數(shù)相比就得到了接收隊列中 sk_buff的平均個數(shù)。TCP直接復(fù)制比率是指從預(yù)收或候補隊列中以計算校驗和并復(fù)制操作直接復(fù)制到用戶空間緩存的數(shù)據(jù)占總接收數(shù)據(jù)的百分比。歸一化回應(yīng)包個數(shù)是目標板發(fā)送給PC回應(yīng)包個數(shù)與TCP層接收到sk_buff對象數(shù)目的比值。測試結(jié)果顯示TCP層收到sk_buff對象的數(shù)目不變。
表1 不同用戶空間緩存下TCP接收相關(guān)測量值Table 1 Measured items related to TCP receiving process with various user space Rx buffer.
由測試條件可知,系統(tǒng)調(diào)用只有復(fù)制了足夠數(shù)據(jù)到用戶空間后才會返回,所以小用戶空間接收緩存會造成更多的系統(tǒng)調(diào)用次數(shù),這不僅增加不在軟中斷中運行的協(xié)議棧接收代碼的時間,還大幅增加系統(tǒng)的額外開銷。當應(yīng)用程序用套接字讀取數(shù)據(jù)時,首先會通過 C庫執(zhí)行 Linux系統(tǒng)調(diào)用進入內(nèi)核空間;然后在內(nèi)核空間通過文件系統(tǒng)抽象層得到該操作對應(yīng)的對象,即套接字層;最后,在套接字層數(shù)據(jù)被復(fù)制到用戶空間。因每一次操作都產(chǎn)生一個層層遞進的額外開銷,所以圖3顯示小接收緩存下系統(tǒng)額外開銷占很大比例。
目標板收到數(shù)據(jù)后需發(fā)送回應(yīng)包給PC。由表1平均通告窗口大小和歸一化回應(yīng)包個數(shù)知,相對大用戶空間緩存情況,小用戶空間緩存下目標板將發(fā)送更多有更小通告窗口大小的回應(yīng)包。更多的回應(yīng)包,增加了軟中斷中運行協(xié)議棧發(fā)送數(shù)據(jù)代碼和網(wǎng)絡(luò)驅(qū)動非中斷響應(yīng)部分的運行時間。由于EMAC發(fā)完數(shù)據(jù)后會產(chǎn)生中斷,所以這也意味著更多中斷,即更多的網(wǎng)絡(luò)驅(qū)動中斷響應(yīng)代碼的運行時間。
由圖1,若在軟中斷上下文中處理了sk_buff對象,只有兩種情況:預(yù)收隊列溢出,或使用當前套接字的應(yīng)用程序運行或休眠在 TCP接收無關(guān)的地方。TCP有流量控制機制,所以當前測試條件下接收數(shù)據(jù)時不應(yīng)出現(xiàn)預(yù)收隊列溢出的情況。測試表明預(yù)收隊列溢出的次數(shù)為0,證實預(yù)收隊列不會溢出。結(jié)合表1和圖3,在系統(tǒng)其它開銷很大,即小用戶空間緩存情況下,軟中斷發(fā)生時應(yīng)用程序運行于TCP接收相關(guān)代碼處的概率降低,導(dǎo)致軟中斷處理sk_buff對象比例增大,增加了系統(tǒng)在軟中斷上下文中接收數(shù)據(jù)的時間。
表1的TCP直接復(fù)制比率表明,小用戶空間接收緩存下收到的數(shù)據(jù)沒有直接達用戶空間,而是通過接收隊列進行了一次中轉(zhuǎn)。測試表明,每個sk_buff對象均包含1448字節(jié)用戶數(shù)據(jù)(包含時間戳選項的TCP包),結(jié)合表1接收隊列中sk_buff的平均個數(shù)算出,用戶緩存小于64 K時,接收隊列中平均數(shù)據(jù)量大于用戶緩存大小。這導(dǎo)致接收隊列不能為空,由圖 1,此時進程不會休眠等待網(wǎng)絡(luò)數(shù)據(jù),則收到的數(shù)據(jù)要么到候補隊列延遲到進程上下文中處理,要么直接在軟中斷中處理。在進程上下文中處理數(shù)據(jù)時,接收隊列先于候補隊列處理,則處理候補隊列時,用戶緩存已被接收隊列填滿,不滿足快速路徑條件,數(shù)據(jù)只能送到接收隊列。同樣,軟中斷中滿足快速路徑條件的概率降低,基本上所有數(shù)據(jù)被送到接收隊列。用戶緩存不小于64 K時,接收隊列中平均數(shù)據(jù)量小于用戶緩存,快速路徑條件易滿足,基本上所有數(shù)據(jù)被直接復(fù)制到用戶空間。
由圖 3,不同用戶緩存條件下,在非軟中斷中運行的接收代碼和網(wǎng)絡(luò)驅(qū)動中斷響應(yīng)部分占用了系統(tǒng)大部分處理器時間。非軟中斷中接收代碼的大部分時間都消耗在sk_buff對象的處理上。由圖1,如進程長時間運行在網(wǎng)絡(luò)接收無關(guān)的地方,則這部分時間會被轉(zhuǎn)移到軟中斷中運行的接收代碼處。所以作為非內(nèi)核開發(fā)者,對Linux 2.4內(nèi)核接收性能優(yōu)化在內(nèi)核層面主要是對網(wǎng)絡(luò)驅(qū)動中斷響應(yīng)部分的優(yōu)化。
結(jié)合上面分析,在應(yīng)用程序?qū)用鎸ο到y(tǒng)性能優(yōu)化主要是盡量減少系統(tǒng)調(diào)用次數(shù),盡量增加直接復(fù)制到用戶空間數(shù)據(jù)的比例,即綜合考慮系統(tǒng)資源和性能前提下,選用合適大小的用戶空間接收緩存。
本文從數(shù)據(jù)流角度分析了 Linux 2.4內(nèi)核TCP/IP協(xié)議棧接收數(shù)據(jù)的過程,并結(jié)合具體測試結(jié)果分析了不同用戶空間緩存條件下系統(tǒng)網(wǎng)絡(luò)接收性能的變化及具體原因,并給出優(yōu)化系統(tǒng)性能的方向。
1 Denis Calvet.IEEE Trans Nucl Sci, 2006, 53(3): 789–794
2 Youichi Igarashi, Hirofumi Fujii, Takeo Higuchi, et al.IEEE Nucl Sci Symp Conf Rec, 2004, 2: 1122–1126
3 Tao N, Chu Y P, Jin G, et al.Plasma Sci Technol, 2005,7(5): 3065–3068
4 Giuseppe Avolio.IEEE Trans Nucl Sci, 2004, 51(5):2081–2085
5 Artur Barczyk, Jean-Pierre Dufey, Clara Gaspar, et al.IEEE Trans Nucl Sci, 2004, 51(3):456–460
6 Ji X L, Li F, Ye M, et al.IEEE Nucl Sci Symp Conf Rec,2008, 2119–2121
7 Won Chulho, Lee Ben, Yu C S, et al.J High Speed Networks, 2004, 13(3): 169–182
8 Bovet D P, Cesati M.Understanding the Linux Kernel.2nd ed, O'Reilly Media, 2002.ISBN: 0-596-00213-0
9 Christian Benvenuti.Understanding Linux Network Internals.O'Reilly Media, 2005.ISBN: 0-596-00255-6
10 Wu W J, Crawford M, Bowden M.Comput Commun,2007, 30(5): 1044–1057
11 Wu W J, Crawford M.International J Commun Syst, 2007,20: 1263–1283
12 Jonathan Corbet, Alessandro Rubini.Linux Device Drivers.2nd ed, O'Reilly Media, 2001.ISBN:0-596-0008-1
13 Stevens W R.TCP/IP Illustrated.Vol 1, The Protocols,Addison-Wesley Professional, 1994.ISBN: 0201633469
14 Clark D D, Van Jacobson, Romkey J, et al.IEEE Commun Mag, 1989, 27(6): 23–29