肖 洋,李廣成,杜 勇
(1.武漢郵電科學研究院,湖北 武漢430074;2.武漢烽火國際技術(shù)有限責任公司,湖北 武漢430074;3.武漢虹信通信技術(shù)有限責任公司,湖北 武漢430074)
隨著智能手機、平板電腦等接入設備的普及,用戶上網(wǎng)更加便捷,致使無線用戶數(shù)量不斷增加,網(wǎng)絡中的用戶流量也在不斷攀升。在現(xiàn)有普遍采用的集中式WLAN的網(wǎng)絡環(huán)境中,數(shù)據(jù)處理的集中點位于接入控制器中,包括用戶數(shù)據(jù)處理、轉(zhuǎn)發(fā)和對用戶、接入點的管理數(shù)據(jù)的處理。對接入控制器數(shù)據(jù)處理的速度提出了很高的要求。在處理數(shù)據(jù)的時候,必然涉及到對內(nèi)存的申請、使用、傳遞和釋放的過程。這個過程的好壞直接決定了系統(tǒng)性能的高低。
由于接入控制器對內(nèi)存的使用比較頻繁,內(nèi)存分配和釋放的效率對整個系統(tǒng)的性能有直接的影響;在接入控制器的系統(tǒng)中,內(nèi)存交互申請和內(nèi)存釋放的過程有可能造成一定量的內(nèi)存泄露情況,一旦出現(xiàn)內(nèi)存泄露,頻繁的內(nèi)存申請釋放操作又會產(chǎn)生大量內(nèi)存碎片,從而極大降低系統(tǒng)整體性能。同時,由于大量的模塊分布在不同的線程之中同時運轉(zhuǎn),內(nèi)存調(diào)度情況不容易掌控,系統(tǒng)整體內(nèi)存使用情況以及各個線程之間的內(nèi)存使用情況也不易把控。因此,需要提出一種內(nèi)存調(diào)度策略,既能夠滿足內(nèi)存的高效回收機制,又能夠有效地管理系統(tǒng)內(nèi)存空間、掌握各個線程中內(nèi)存分配的信息。
現(xiàn)有通用的接入控制器主要采用集中式組網(wǎng)方式,接入控制器負責管理AP以及STA,負責數(shù)據(jù)的快速轉(zhuǎn)發(fā),其基本模塊組成如圖1所示。由報文快速轉(zhuǎn)發(fā)模塊、用戶管理模塊、業(yè)務管理模塊以及系統(tǒng)管理維護模塊構(gòu)成[1]。其中,報文快速轉(zhuǎn)發(fā)模塊由報文接收/發(fā)送和報文處理模塊組成,負責對接入控制器內(nèi)外報文進行篩選分類,并根據(jù)網(wǎng)絡協(xié)議規(guī)則轉(zhuǎn)發(fā)到相應模塊或網(wǎng)絡接口上,對模塊性能的要求較高;用戶管理模塊和業(yè)務管理模塊分別負責對接入用戶以及AP的狀態(tài)等上下文進行管理維護。系統(tǒng)管理維護模塊是對整個接入控制器系統(tǒng)進行統(tǒng)一管理與狀態(tài)監(jiān)控的模塊。根據(jù)這三大模塊的構(gòu)成,可以按照數(shù)據(jù)處理分為三大部分:報文快速轉(zhuǎn)發(fā)部分、系統(tǒng)線程內(nèi)處理部分以及系統(tǒng)線程間處理部分。
快速轉(zhuǎn)發(fā)部分指從網(wǎng)絡中收到的數(shù)據(jù)增減頭部隧道封裝并快速轉(zhuǎn)發(fā)出去,該過程會頻繁地為數(shù)據(jù)分配內(nèi)存,并將其需要的數(shù)據(jù)拷貝數(shù)次,處理后輸出。
圖1 AC的多板構(gòu)架及模塊組成
系統(tǒng)線程間數(shù)據(jù)處理是指在系統(tǒng)線程間的數(shù)據(jù)處理,涉及到線程間的通信機制,以及內(nèi)存相互訪問和調(diào)度。
系統(tǒng)線程內(nèi)處理數(shù)據(jù)部分指在系統(tǒng)線程內(nèi)部處理的數(shù)據(jù),通常為線程私用的數(shù)據(jù),包括用戶上下文、WTP上下文等,申請釋放的頻率相對較低。
針對接入控制器以上幾種內(nèi)存使用的特點,可以將接入控制器內(nèi)存調(diào)度分層3個層次:Dynamic Smart Preallocation(DSPA),Static Pre-allocation(SPA),Dynamic Pre-allocation(DPA)。
DSPA適用于快速轉(zhuǎn)發(fā)功能,實現(xiàn)預分配內(nèi)存,并對分配內(nèi)存大小進行預估,不足的時候就按照一定規(guī)律進行鏈式增加,優(yōu)化分配機制,在處理的過程中實現(xiàn)一次拷貝多次使用。
SPA適用于線程間的內(nèi)存分配。實現(xiàn)預分配內(nèi)存、大小固定、匹配內(nèi)存空間[2]。
DPA適用于線程內(nèi)部處理的內(nèi)存使用,實現(xiàn)按需分配,匹配內(nèi)存空間,會有一些內(nèi)存空間的浪費。
以上3種層次的內(nèi)存分配方式都能夠?qū)崿F(xiàn)內(nèi)存快速調(diào)度,對應用每次分配以及釋放動作的代碼段進行定位,確認內(nèi)存泄露與否,以避免內(nèi)存碎片產(chǎn)生。在接入控制器系統(tǒng)發(fā)生異常的時候,應用定位問題具有方便快速定位的優(yōu)勢。
基于以上功能需求,對AC內(nèi)存調(diào)度的設計分為內(nèi)存分配層和內(nèi)存管理層2個層次,其中內(nèi)存分配層提供內(nèi)存分配釋放,為上層應用提供快速穩(wěn)定的存儲基本服務,而內(nèi)存管理就在內(nèi)存分配之后,對內(nèi)存信息進行統(tǒng)一管理,并對異常內(nèi)存分配或釋放進行記錄。下面分別對兩個層次的設計原理進行詳細的介紹。
在AC線程內(nèi)部及線程間,均采用內(nèi)存池陣列的方式對內(nèi)存進行分配。內(nèi)存池陣列中有數(shù)個內(nèi)存池,每個內(nèi)存池中內(nèi)存大小相同[3]。
SPA內(nèi)存分配方式使用于線程之間的大小固定的應用環(huán)境下,當應用的某一種相同的數(shù)據(jù)結(jié)構(gòu)數(shù)量較大,使用較為頻繁的時候,如ARP表項、用戶上下文、AP上下文等,在使用的時候,只需創(chuàng)建適合其使用固定大小的內(nèi)存池,并每次從指定的內(nèi)存池中分配釋放內(nèi)存即可,其時間復雜度為O(1)。效率極高,但是使用環(huán)境也有限制,而且需要應用對該內(nèi)存池的大小進行設定。
在AC的報文快速轉(zhuǎn)發(fā)模塊中,一般會從網(wǎng)絡接口接收數(shù)據(jù)包。每當收到數(shù)據(jù)包,就會為這些數(shù)據(jù)包分配內(nèi)存。為了實現(xiàn)零拷貝,每次從DSPA內(nèi)存池中,分配1塊內(nèi)存,該內(nèi)存結(jié)構(gòu)如圖2所示。是一種緩沖鏈式結(jié)構(gòu),由1個DSPA描述符以及DSPA內(nèi)存塊組成。上層應用需要為其增加或減少數(shù)據(jù)頭,就只用將指針向前偏移一部分,并填充相應的數(shù)據(jù)部分即可。若需要在該數(shù)據(jù)包后繼續(xù)填充數(shù)據(jù),只需繼續(xù)增加1個DSPA內(nèi)存塊,并將之前的DSPA用指針指向新增的內(nèi)存塊,保證關(guān)聯(lián)關(guān)系。應用處理之后,將其轉(zhuǎn)到發(fā)送端口,將數(shù)據(jù)轉(zhuǎn)出。這就是數(shù)據(jù)的快速轉(zhuǎn)發(fā)過程。由于每個DSPA內(nèi)存塊都是固定大小,在分配內(nèi)存的過程中,適合于高效數(shù)據(jù)快速轉(zhuǎn)發(fā),而在其他環(huán)境中不夠靈活。
圖2 DSPA內(nèi)存分配結(jié)構(gòu)
其中,在DSPA的工作流程圖如圖3所示。
圖3 DSPA內(nèi)存分配流程圖
DPA分配內(nèi)存的模式為根據(jù)應用申請的內(nèi)存大小,與2n進行比較(2n為計算機存儲特性的一個參考值),匹配需要申請的內(nèi)存池。若該內(nèi)存池的內(nèi)存分配完了,就會動態(tài)分配新的大小相同的內(nèi)存池,為應用繼續(xù)提供內(nèi)存。其中在DPA的工作流程圖如圖4、圖5所示。
在以上3種工作模式下,分配和釋放內(nèi)存的時候都會為每個內(nèi)存打上標簽,分別記錄分配內(nèi)存的函數(shù)、文件、行號、及分配的時間。每個內(nèi)存都有1個內(nèi)存使用標志位,用于表示該內(nèi)存使用情況[4-5]。其中-1表示從未使用過,0表示被釋放,1表示被分配。為內(nèi)存管理模塊其配置命令行,在調(diào)試工作模式下,提供分析問題的幫助。
1)為用戶分配內(nèi)存提供定位信息
當用戶分配內(nèi)存的時候,就會將內(nèi)存分配的情況記錄下來,并與內(nèi)存池的上下文綁定。已分配的內(nèi)存塊會將內(nèi)存使用標志位置為1。
2)為用戶釋放內(nèi)存提供定位信息
當用戶釋放內(nèi)存的時候,就會將內(nèi)存釋放的情況記錄下來,并與內(nèi)存池的上下文綁定。并且可以和1中的信息進行比對,判斷內(nèi)存是否存在內(nèi)存泄露。
3)為用戶非法內(nèi)存操作提供信息
(1)double free
在程序員編程過程中,某一個內(nèi)存用于存儲上下文,共用于數(shù)個線程中,在釋放的過程中可能存在重復釋放的情況。如果在調(diào)用malloc-free函數(shù)的時候,程序就會掛掉,并留下double free的信息。本文會根據(jù)flag位來判斷,如果flag為0,應用又釋放一次內(nèi)存,即發(fā)生double free。在內(nèi)存管理中會記錄double free的錯誤,并保證程序不會因此異常退出。
(2)釋放非法地址內(nèi)存
在程序員編程過程中,釋放非法的內(nèi)存地址,如未對齊的內(nèi)存塊地址、空地址或不存在于內(nèi)存池中,避免造成程序的異常退出。其調(diào)用釋放函數(shù)的跟蹤信息都會被記錄到日志信息中,便于后續(xù)定位處理問題。
4)為可能出現(xiàn)內(nèi)存泄露的內(nèi)存提供信息
在程序員編程過程中,或多或少都會出現(xiàn)一些內(nèi)存泄露的問題,通過標志位以及調(diào)用信息可以容易地定位到內(nèi)存塊的狀態(tài),在正常的內(nèi)存使用中,大部分的內(nèi)存都是不斷地分配然后釋放。因此,在每個內(nèi)存分配的時候中,就會在內(nèi)存塊中增加1個時間戳信息,如果1個內(nèi)存塊在運行時長大于1周的時候還沒有被釋放,就會將這個內(nèi)存塊的地址調(diào)用信息記錄到日志信息中,便于程序員定位分析。
根據(jù)以上內(nèi)存調(diào)度的分析設計,通過在Linux C下實現(xiàn)內(nèi)存調(diào)度方法?,F(xiàn)從內(nèi)存調(diào)度功能和性能2個方面來驗證本文設計方案。
內(nèi)存調(diào)度功能測試即對內(nèi)存管理的測試。在實際Linux系統(tǒng)中只能通過系統(tǒng)的命令行查看整個系統(tǒng)以及每個進程的內(nèi)存使用情況。通過系統(tǒng)的接口對程序的分析不能有很大的幫助,如圖6所示。
圖6 系統(tǒng)對內(nèi)存使用情況統(tǒng)計(截圖)
基于內(nèi)存調(diào)度對內(nèi)存的管理,可以清晰地打印出內(nèi)存 的使用情況,其實現(xiàn)如圖7~圖10所示。
內(nèi)存調(diào)度性能測試即對內(nèi)存分配釋放的性能的一個測試。在內(nèi)存調(diào)度過程中,測試的環(huán)境為mips構(gòu)架,CPU為Cavium Octeon CN5650,內(nèi)存為8 Gbit。將本內(nèi)存調(diào)度與直接調(diào)用系統(tǒng)API malloc/free函數(shù)接口測試對比。結(jié)果如表1所示。
通過對比,可以清晰地看出通過內(nèi)存池調(diào)度的內(nèi)存通過空間換取更快的分配釋放時間,提供了更加高效的內(nèi)存分配機制。
表1 內(nèi)存性能對比測試 μs
本文設計的內(nèi)存調(diào)度方式是適用于當前各種構(gòu)架的接入控制器底層的一種內(nèi)存調(diào)度策略。在以SPA,DSPA,SPA三種層次的內(nèi)存分配方式上為上層應用提供高速可靠的內(nèi)存分配策略,與此同時能夠定位內(nèi)存調(diào)用模塊以及內(nèi)存泄露問題,避免內(nèi)存碎片的產(chǎn)生導致系統(tǒng)性能的降低,大大增加接入控制器在大流量多用戶的情況下的運行性能以及穩(wěn)定性。
[1]STEVENS W R.Unix Network Programming[M].Englewood Cliff:Prentice Hall,1990.
[2]MCKEE S,KLENKE R,WRIGHT K,et al.Smarter Memory Improving Bandwidth for Streamed References[J].IEEE Computer,1998,31(7):51-63.
[3]顧勝元.嵌入式實時動態(tài)內(nèi)存管理機制[J].計算機工程,2009(20):1-3.
[4]JAMES F,KEITH W.Computer Networking:A Top-Down Approach[M].5th ed.New Jersey:Addison Wesley,2010.
[5]SCHUMANN R C.Design of the 21174 Memory Controller for Digital Personal Workstations[J].Digital Technical Journal,1997,9(2):57-70.