文 豪,葉江峰,孫 磊,吳 輝
(中國工程物理研究院 電子工程研究所,四川 綿陽 621900)
隨著信息化進程的加快,電磁環境的日趨復雜,新的信號體制及應用需求層出不窮,以往那種功能單一、靈活性不足的無線電信號處理系統已遠不能適應當前靈活多變的應用需求[1]。為此,軟件無線電(SDR)技術從20世紀90年代以后逐漸興起[2]。其思想是通過構造一個具有開放性、標準化和模塊化的通用硬件平臺,使無線通信系統具有高度靈活性、開放性[3]。由此,美軍通過聯合戰術無線電系統(JTRS)制定了軟件體系結構(SCA)規范[4],該標準體系結構為開發提供統一的、開放式的底層支持和服務,保證了軟件組件的可移植性和可重用性[5]。但SCA規范僅能用于指導軟件無線電通信系統整體的設計開發,并沒有給出具體的實現方法。目前,大多數SCA波形組件開發方法都較為繁瑣復雜,技術門檻較高,由此勢必給波形開發人員帶來很大的開發難度,造成開發周期延長、開發成本上升和測試工作量顯著增加等問題[6]。同時,傳統波形組件不滿足分布式部署與跨平臺等需求,并不適用于搭建原理性的驗證系統。
針對上述問題,本文引入SOA(Service Oriented Architecture)的設計理念,將其應用于信號處理領域,采用更加簡潔優秀的ICE(Internet Communications Engine)中間件技術構建出新的信號處理系統架構模型。該模型不僅具有很好的可移植性和可重用性,還具備自動化服務組件封裝能力,極大簡化了組件開發過程。
另一方面,隨著集群技術的發展,以通用的計算機平臺來替代專用的DSP和FPGA等硬件來進行軟件數字信號處理也成為業界熱門的研究方向[7]。本文設計采用“分布式”的服務架構,解決并行化處理、平臺異構等問題,使系統能通過增加處理節點提高處理能力,以滿足大數據量信號處理的實時性要求。
系統的分層體系結構參考模型如圖1所示,其主要包括:軟硬件資源、分布式服務總線、服務集成開發環境、基礎服務層、服務組件層、業務服務層和應用系統層。

圖1 模型分層體系結構
軟硬件資源:為實現最大的性能提升及硬件擴展能力,模型支持相對復雜軟硬件資源,主要包括數據庫、分布式文件系統、GPP資源和GPU資源等。這些資源用來為系統提供計算資源、數據存取資源,支撐上層各類服務和應用的運行。
分布式服務總線:作為服務框架的核心組成,主要負責適配并連接各服務組件執行系統業務功能,包括服務管理、服務注冊中心、基礎數據服務、接口適配和消息分發(基于ZeroMQ)等模塊。
服務集成開發環境:服務組件開發工具。支持C++語言框架代碼自動生成,幫助開發者完成服務的開發。更重要的是能夠實現Matlab文件的服務自動轉換,直接生成滿足ICE接口規范的服務發布包。
基礎服務層:由各種基礎服務組成,包括數據分發、數據存儲、數據源、異常處理和資源調度等。其主要作用是通過服務封裝把軟硬件資源抽象成服務對象,使調用者不必關心底層驅動和數據管理。
服務組件層:服務組件是開發人員需要自行設計實現的最小系統組成單元,通常為不可以再拆分且可復用的算法單元。應用服務集成開發環境可實現服務組件的快速開發。
業務服務層:通常由服務組件組合而成,通過組合和流程編排形成業務服務(也稱為組合服務),實現具體的業務功能。
應用系統層:作為直接面向用戶的應用系統,接收來自服務端的推送信息予以顯示。用戶界面開發采用了QT插件框架技術,可實現界面的靈活布局,具備良好擴展性和跨平臺能力。
分布式服務架構擁有以下特性:
簡便的開發過程:可以對符合格式規范的算法源代碼進行直接的服務轉化,而不用針對該平臺重新設計開發服務組件,極大地降低了系統開發難度,也節省了開發時間。
多語言支持:通過使用標準的接口定義,使得服務組件支持C++,Matlab,Java語言開發。
跨平臺特性:服務組件可以運行在不同的操作系統和機器架構上,并且可以使用多種網絡協議進行通信。
良好的系統伸縮性:服務組件可任意分布在多個服務器上,系統的最大運算效率可以隨著系統硬件資源的增加而提高。
整體而言,該架構具有良好的開放性,能夠適應將來的業務拓展需求,有效地提高服務利用率,減少開發成本。
新信號處理系統的研發,通常需要在Matlab仿真基礎上,再進行軟件應用程序的開發或者硬件設備的研制,從而評估新系統架構的合理性[8]。但這一過程通常需要多次迭代,使得這種研發模式面臨著周期長、成本高的困境。本文設計了一種名為“服務集成開發環境”的軟件,可方便地把C++和Matlab程序轉化為服務組件,部署于分布式服務架構中就可快速驗證系統的可行性。
因為ICE本身對C++具有良好的支持[9],通過C++源代碼生成服務組件,本文不做贅述。而Matlab卻是信號處理領域實現系統仿真應用最多的工具,所以,解決Matlab程序的服務快速開發才是簡化組件開發的關鍵。Matlab程序轉化的服務包封裝結構如圖2所示。

圖2 Matlab程序轉化的服務包封裝結構
Matlab程序轉化的服務包封裝的步驟如下:
① 為實現服務的轉化,Matlab程序編寫必須符合一定規范,其具體函數形式如下:
function[strRes,Output1,...] = 函數名(Input1,Input2,Input3,...)
函數參數被分別定義為輸出參數、輸入參數和配置參數。輸出參數在等號左側,strRes被定義為調試信息輸出結構體;輸入參數在等號右側;配置參數也是輸入參數,但在注釋中加入了Config關鍵字用來識別。
② 本文設計的服務集成開發環境會對文件內容及注釋信息進行格式檢查,對滿足規范的文件則調用Matlab自帶的mcc編譯器,編譯出符合C語言規范的DLL文件及頭文件形成一層封裝。
③ 實現DLL文件向ICE服務轉化。這個過程比較復雜,但最關鍵的就是數據類型的轉化。我們知道,Matlab所有的計算都基于一種名為mxArray的數據結構,雖然Matlab提供了數據轉換函數mlfScalar()和mxGetPr(),但其依賴Matlab環境,不便于系統獨立運行。為被上層的ICE函數調用,必須把ICE函數輸入參數從C數據類型轉化為mwArray類型并傳遞給DLL中的函數。本文設計了一組“mwArrayEx”的模板類,通過該模板類解決了輸入參數的數據類型轉化。示例如下:
template<>
classmwArrayEx
{
public:
mwArrayEx(const string& data)
:m_Data(data)
{
}
~mwArrayEx(void)
{
}
operator mwArray()
{
return mwArray(m_Data.c_str());
∥不同數據類型,獲取方式不同
}
private:
const string m_Data;
};
相反,ICE函數的輸出參數則需要從mwArray類型轉化為C數據類型。本文通過設計定義一組名為“Dataconvert”的模板函數轉化Matlab矩陣數據為數組結構來解決上述問題。由于原理類似,這里不做贅述。2種模板解決了Matlab程序與C++數據類型的相互轉化問題,使得函數能夠嚴格按照ICE規范實現服務的封裝。
依照以上設計原理,服務集成開發環境被設計為一個自動化的開發轉化工具,系統集成人員不需要了解具體算法,只需要應用該工具轉化目標文件(m文件或Cpp文件)為服務包,發布并部署于集群服務器,再通過服務管理軟件對服務流程組合編排就可以完成系統開發。開發環境的服務轉化流程如圖3所示。

圖3 服務開發環境服務轉化實現流程
具體步驟如下:
① 開發人員首先選擇需要轉化的目標文件,可以是C++或Matlab語言。
② 軟件驗證目標文件并根據函數定義及其注釋生成ICE接口文件[10]。同時,生成“mwArrayEx”和“Dataconvert”源文件,供類型轉化函數調用。
③ 軟件判斷需要轉化的源程序語言類型,如果是C++源程序直接通過ICE接口文件生成對應的*I.h和*I.cpp、*ServerI.h和*IServer.cpp等服務源文件;如果是Matlab語言源程序需要通過調用mcc生成動態鏈接庫,并進行數據類型轉化后再生成服務源程序。
④ 軟件生成XML格式的服務配置文件,主要包括:服務名稱、服務類型、配置參數、出入參數和輸出參數等信息。
⑤ 軟件生成整個服務工程文件(.sln),自動調用VS2010編譯器對工程進行編譯,生成服務包。
不難看出,本文設計開發的服務集成開發環境為用戶提供了自動化的服務開發能力。使得系統開發人員不需要了解具體算法設計及ICE開發規范就可以自動生成服務開發包(包括服務框架代碼、服務描述文件以及接口定義文件等)用以組合成業務系統。通過讓算法設計、組件開發和系統集成3個過程的相互分離,降低了服務開發及系統集成的難度。
當前信號處理系統通常具有高吞吐率、大數據量的特點,從而要求系統具備高速的數據處理能力。現在很多基于通用硬件的軟件無線電平臺(如GNU Radio+USRP組合、微軟的SORA等),由于基于組件模型設計思想,僅僅只有通過優化CPU訪問來提高運算效率,導致運算能力始終有限[11]。為解決運算性能瓶頸的問題,通過把各個計算任務分發到多個處理節點,充分利用計算機集群的計算機資源實現并行運算,才是比較有效的解決方案。
本文服務架構模型的基礎思想是就是讓業務組件以服務的形式存在于分布式系統中,服務間相對獨立、自包含、可重用,業務流程及系統功能由服務組裝和流程編排來實現[12]。為實現這種設計理念,本文的系統架構可大致分為核心框架、注冊中心和應用客戶端3個部分,如圖4所示。

圖4 架構原理
核心框架扮演“服務提供者”角色,為請求者提供服務[11]。核心框架不僅作為服務部署的容器,還實現了服務管理、狀態監控、流程編排與執行、計算資源的負載均衡以及服務節點故障容錯等功能。
注冊中心采用ZooKeeper實現諸如統一命名服務、配置管理、分布式服務鎖以及集群管理等功能[12]。
應用系統作為“服務請求者”,通過服務訪問模塊向注冊中心查詢服務信息,并調用服務框架中的相應服務。
服務作為實現不同功能單元的自包容實體部署于核心框架中,通過服務組合的方式實現彼此的交互及數據交換,最終實現應用系統的業務功能[13]。
為實現較高的資源利用率,本文采用前置負載計算的方式,在服務調用之前根據負載均衡策略,將任務請求轉發到具體的服務框架節點上[14]。
首先,服務節點會定時將服務的運行信息(CPU占用率、線程數、服務調用次數、平均處理時間以及調用失敗次數等)上報到注冊中心的資源調度模塊上。資源調度模塊維護著一個負載信息表(LIT),該表存放著服務器ID、服務器IP、當前線程數Si、最大線程數max(Si)、負載參數Li、當前負載LSi以及最大負載max(LSi)等信息。
資源調度模塊根據服務節點的運行信息,假設有4項:C1,C2,C3,C4,負載參數各自的權值為Ki,其負載參數計算公式為:

(1)
系統實時取得各服務器中的服務調用線程數Si,各服務器根據此數據與此服務器最大能接受的請求線程數的比值Si/max(Si)作為各服務器負載的初始數據。由于服務類型的不同,每個服務占用的服務器資源也有差別,Li作為周期性從各服務器收集到的負載信息,被用作糾偏因子,用來糾正負載信息的誤差。集群中每個服務器最終負載計算公式為:
LSi=Si/max(Si)+KLi,
(2)
式中,K為Li的系數。
根據式(1)和式(2)計算出每個服務器最終的負載信息LSi,用LSi與服務器最大負載max(LSi)的比值來調整服務調用資源。采用服務調用平均時間最小為負載均衡策略,該比值越小,說明服務調用的平均時間越小,任務請求選擇最小耗時的服務節點進行訪問,從而達到負載均衡的目的。
為驗證框架的有效性,基于該框架設計實現了1個并行處理2個業務流程的信號處理系統。如圖5所示,其數據源是事先采集的數據文件,業務服務的處理結果通過通用數據處理服務推送給信號處理軟件進行可視化界面展示。

圖5 基于服務框架的驗證應用系統
通用數據處理服務是本框架提供的基礎服務(采用數據分發服務DDS實現),其功能是通過訂閱分發機制[15],實現運算結果向用戶界面、數據庫和文件系統的訂閱分發。該服務使得系統的界面顯示或存儲數據與數據處理業務服務解耦和[16],從而保證系統的數據處理性能不受影響。
服務管理軟件能夠(如圖6所示)用可視化方式,把服務框架中已部署好的算法服務,按照實際業務流程連接組合起來,形成一組業務流程[17]。該軟件是管理服務框架的核心軟件,通過訪問注冊中心和服務容器可實現包括服務部署、注冊、組合和狀態監控等綜合管理功能[18]。

圖6 服務管理軟件界面
在驗證系統中準備了2臺服務器,以驗證分布式運行環境下框架性能。采用大小為1 GB的采樣信號數據文件進行測試,設置服務處理每包數據緩存為100 KB。組合并配置業務流程1輸出信號參數及頻譜數據,業務流程2輸出分析結果及星座圖。具體測試環境為CPU E5-263 0 v3 2.40 GHz 8C(×2)、內存64 GB、操作系統Windows Server 2008 SP1,網絡帶寬100 MB/s。針對不同節點數(2個節點以上,等數量分別部署),不同線程數量,對該系統進行了性能測試,其測試結果如圖7所示。

圖7 算法性能測試結果
可以看出單一節點單一線程的應用計算耗時較長,但在開啟多線程調用更多計算資源后[18],運算性能明顯提升。這說明該分布式運行框架可通過擴展硬件資源,有效提高運行處理速度。
本文設計的分布式服務架構是一種針對信號處理領域的開放式體系架構,通過服務總線技術提高軟件的復用度、系統的擴展性[19]。通過服務封裝使工程師可以快速搭建基于計算機集群軟件無線電系統,并通過分布式并行運算來提高系統運行效率[20]。實驗結果表明,框架滿足大數據應用處理需求,有一定的應用價值。