王 榮,王建新,陳 向,盛 羽
中南大學(xué) 信息科學(xué)與工程學(xué)院,長沙 410083
數(shù)字圖像處理作為一門非常實用的學(xué)科,它一直是高校教學(xué)的重點和難點。學(xué)生通過實驗對所學(xué)的算法進行實現(xiàn)、改進以及重新設(shè)計,并對算法的處理效果進行分析和比較,從而能增進對算法的了解[1]。數(shù)字圖像算法抽象,涉及的公式一般比較復(fù)雜。學(xué)生可以通過C、C++[2]和Java[3]等高級編程語言來實現(xiàn)數(shù)字圖像處理算法,也可以調(diào)用MATLAB圖像處理工具箱[4-5]、OPenCV[6]和ImageJ]7]集成的數(shù)字圖像算法庫構(gòu)建復(fù)雜的實驗流程。不論是自己編程還是使用MATLAB和OPenCV等提供的圖像處理工具都需要配置硬件設(shè)施和運行環(huán)境,在預(yù)定的機器上進行實驗。顯然在移動設(shè)備上傳統(tǒng)模式不能很好地支撐,用戶無法隨時隨地進行實驗。文獻[8]提出了基于Khoros平臺開發(fā)的數(shù)字圖像處理系統(tǒng),該系統(tǒng)實現(xiàn)了豐富的圖像處理算法,并提供了Internet的訪問功能,但是該系統(tǒng)沒有提供靈活的實驗流程定制方案,缺乏交互性。文獻[9]提出了基于CORBA技術(shù)的多語言集成平臺,但是CORBA技術(shù)使用IIOP協(xié)議很難穿透防火墻,因此該平臺只適用于局域網(wǎng)內(nèi)部的資源集成,無法實現(xiàn)跨Internet的異構(gòu)資源集成和計算協(xié)同。文獻[10]提出了異構(gòu)資源集成的虛擬實驗平臺,該系統(tǒng)采用Web服務(wù)技術(shù)實現(xiàn)了Java和MATLAB的集成,在定制實驗流程和實現(xiàn)組件的分布式管理方面做了探索和研究,取得了有益的進展。但是該系統(tǒng)的客戶端使用Applet,通過RMI/IIOP直接訪問JavaBean來獲得信息,迫使防火墻開放相應(yīng)信息的端口,使系統(tǒng)存在潛在的不安全性隱患。
針對以上問題,本文設(shè)計并實現(xiàn)了一個面向異構(gòu)資源集成的數(shù)字圖像實驗平臺。該平臺實現(xiàn)了以下目標(biāo):
(1)支持多種語言編寫的算法組件間的交互。所支持的編程語言包括:Java、C++、Python、MATLAB 和OpenCV等工具軟件。
(2)支持用戶將自己編寫的算法源代碼按照平臺的相應(yīng)規(guī)則提交到平臺中并與平臺其他代碼集成運行。
(3)支持用戶自行選擇圖像算法組件構(gòu)建實驗流程。
針對以上設(shè)計目標(biāo),本文提出的平臺架構(gòu)如圖1所示。平臺主要由Nignx服務(wù)器、Web應(yīng)用服務(wù)器、實驗調(diào)度服務(wù)器、算法組件服務(wù)集群和數(shù)據(jù)庫存儲服務(wù)器5部分組成,各部分的作用如下:
(1)Nignx服務(wù)器:負載均衡服務(wù)器處理用戶請求。采用ip_hash作為負載均衡方式來實現(xiàn)session共享和解決文件上傳下載的問題,使同一個用戶的請求對應(yīng)訪問同一個后端服務(wù)器。
(2)Web應(yīng)用服務(wù)器:用戶通過Internet與Web應(yīng)用服務(wù)器進行交互,比如用戶提交自定義組件、注冊組件服務(wù)和創(chuàng)建實驗流程等。Web應(yīng)用服務(wù)器采用MVC模式將操作界面、數(shù)據(jù)模型和業(yè)務(wù)邏輯解耦和。表示層向用戶提供友好的實驗操作界面,用戶請求控制器對封裝的實驗或組件數(shù)據(jù)進行解析??刂破饔脕斫邮沼脩籼峤坏恼埱?,將請求傳來的JSON數(shù)據(jù)轉(zhuǎn)換成模型中對應(yīng)的數(shù)據(jù)模型,然后調(diào)用相應(yīng)的業(yè)務(wù)方法并根據(jù)調(diào)用結(jié)果選擇返回視圖。
(3)數(shù)據(jù)庫存儲服務(wù)器:負責(zé)平臺數(shù)據(jù)的持久化存儲,主要存儲組件、實驗信息和監(jiān)控信息等。平臺對數(shù)據(jù)一致性和復(fù)雜查詢沒有特別需求,因此采用了流行的NoSQL數(shù)據(jù)庫MongoDB[11],搭建一主兩從的集群,提高了數(shù)據(jù)高并發(fā)讀寫效率和降低了擴展難度。
(4)調(diào)度服務(wù)器:采用線程池技術(shù)異步獲取處于待處理的實驗并采用RPC技術(shù)遠程調(diào)用算法組件服務(wù)器的服務(wù)接口進行實驗處理,最后負責(zé)將實驗結(jié)果進行持久化存儲。
(5)算法組件服務(wù)集群:承載了C++、MATLAB、Java和Python等語言的算法組件同時提供對外服務(wù)接口,算法服務(wù)之間通過RPC技術(shù)進行信息傳遞。為了提高算法組件運行速度,確保算法服務(wù)器的可維護性,后臺集群按照語言種類進行機器資源的分配,即不同語言使用不同的機器對外提供服務(wù)。
圖1 平臺架構(gòu)圖
數(shù)字圖像處理課程實驗中的核心為各種圖像處理算法,學(xué)生通過各種算法的組合來完成實驗以獲取圖像處理結(jié)果。為了提高用戶實驗的便利性,實現(xiàn)對多語言的支持,平臺將各種數(shù)字圖像常用的算法進行構(gòu)件化,以供用戶選擇、組合和使用。
平臺中的算法構(gòu)件主要包括算法核心代碼、算法相關(guān)參數(shù)、Thrif框架代碼等幾個方面。其中Thrift框架代碼為算法服務(wù)的調(diào)用提供相關(guān)接口,算法核心代碼則是實現(xiàn)算法功能的核心部分,算法相關(guān)參數(shù)則包括上下文參數(shù)和屬性參數(shù)兩種。上下文參數(shù)即算法的輸入和輸出參數(shù),在本平臺中,輸入輸出參數(shù)均為數(shù)字圖像類型。屬性參數(shù)則是算法執(zhí)行過程中對算法執(zhí)行結(jié)果產(chǎn)生影響的參數(shù)。
算法構(gòu)件交互涉及4種角色:服務(wù)發(fā)布者、服務(wù)注冊中心、算法服務(wù)群和服務(wù)請求者。角色交互如圖2所示。
圖2 組件服務(wù)化交互圖
服務(wù)發(fā)布者在平臺的Web界面中提交算法的核心代碼并配置相關(guān)的參數(shù)。平臺將對用戶所提交的核心代碼進行編譯并將編譯通過的代碼,相關(guān)參數(shù)與Thrift框架進行融合形成Thrift服務(wù)構(gòu)件形成服務(wù)群,并將調(diào)用信息發(fā)布到注冊中心,從而完成算法構(gòu)件的發(fā)布。算法構(gòu)件的核心屬性包括serviceUrl、nameSpace、method-Name、comDepict和 paramArr。serviceUrl記錄組件服務(wù)地址,包含調(diào)用服務(wù)的IP和端口號,它決定了調(diào)用分布式服務(wù)的地址。nameSpace記錄組件服務(wù)名,method-Name記錄組件調(diào)用方法名,paramArr用來表示參數(shù)信息列表。參數(shù)屬性的校驗,則是用算法服務(wù)器對算法解析得到的參數(shù)跟用戶注冊組件描述的參數(shù)進行匹配的過程。對于從算法源碼層面解析獲取參數(shù)的方式,Java根據(jù)用戶注冊提交的調(diào)用方法,通過反射機制獲得方法的參數(shù)類型、參數(shù)名和返回值類型。MATLAB和C++則通過文本解析得到算法組件代碼的參數(shù)定義行,從而解析出方法的參數(shù)名、參數(shù)類型和參數(shù)返回值。
組件服務(wù)調(diào)用則是處理實驗流程中組件之間的交互。根據(jù)用戶的偏好,各算法組件可能由不同的編程語言來開發(fā),因此平臺需要提供跨語言的程序調(diào)用。目前支持跨語言遠程調(diào)用的技術(shù)主要有:阿里巴巴的Dubbo[12]、Hsf[13],F(xiàn)acebook 的 Thrift[14],Google的 Grpc[15],Twitter的Finagle等[16]。在這些RPC中,F(xiàn)acebook的Thrift支持更多語言的消息格式,它具有自己內(nèi)部定義的傳輸協(xié)議規(guī)范和傳輸數(shù)據(jù)標(biāo)準(zhǔn),可以和已經(jīng)有的Web服務(wù)器進行無縫組合,同時它還為服務(wù)器提供了多種模式的運行機制,包含阻塞、非阻塞,單線程和多線程等。Thrift文件生成的目標(biāo)代碼簡單易用,包含完整的客戶端/服務(wù)端堆棧,能快速實現(xiàn)RPC,因此Atlas使用Thrift搭建虛擬實驗室平臺調(diào)度系統(tǒng)之間的橋梁,通過運行腳本對傳輸數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)和業(yè)務(wù)邏輯根據(jù)不同的運行環(huán)境快速構(gòu)建相應(yīng)的代碼,同時根據(jù)Thrift內(nèi)部序列化機制對傳輸?shù)臄?shù)據(jù)進行簡化和壓縮。綜合平臺需求和Thrift技術(shù),本文設(shè)計Thrift接口腳本文件ImageTService,只需用Thrift腳本語言把下面的IDL編譯成對應(yīng)語言的客戶端和服務(wù)端,就可以實現(xiàn)異構(gòu)語言間的相互調(diào)用,腳本內(nèi)容如下所示:
struct ErrorCodeType{
1:i32 errorCode,
2:optional string message,
}
exception ImageTException{
1:i32 errorCode,
2:optional string message,
}
struct KeyValue{
1:string key,
2:optional string value,
3:bool pid,
}
struct ImageTResult{
1:ErrorCodeType errorCodeType,
}
service ImageTService{
ImageTResultexecute(1:stringcodeName,2:string codeUrl,3:string codeMethod,4:list
ImageTResultfixParameter(1:string id,2:KeyValue keyValue,3:String runPath)throws(1:ImageTException e)
}
ImageTService服務(wù)接口中的execute方法是組件對調(diào)度服務(wù)器提供的調(diào)用方法,在調(diào)度服務(wù)器向算法服務(wù)器傳輸組件信息時被調(diào)用。調(diào)度服務(wù)器處理實驗流程時會去注冊中心查詢算法服務(wù)的調(diào)用地址,并將實驗流程中的算法組件進行信息初始化和任務(wù)的分發(fā)。code-Name、codeUrl和codeMethod唯一確定服務(wù)調(diào)用的定位信息,keyvalues則為組件初始化參數(shù)對象列表,nextNodeArr表示組件對象的子節(jié)點調(diào)用信息集合,算法服務(wù)器接收到調(diào)度服務(wù)器請求時,會將當(dāng)前任務(wù)插入準(zhǔn)備隊列,等待父組件信息傳遞直到組件運行參數(shù)就緒,該組件會被移動到就緒隊列等待服務(wù)的啟動,組件運行完成后,會依次調(diào)用子節(jié)點的fixParameter方法將運行結(jié)果傳遞下去。在fixParameter方法中,id用來唯一確定準(zhǔn)備隊列中的組件任務(wù),keyValue則為父節(jié)點的運行結(jié)果信息,runPath紀(jì)錄了當(dāng)前鏈路的運行路徑。ImageTResult定義返回結(jié)果,包含錯誤信息結(jié)構(gòu)體ImageTException,由錯誤碼和錯誤信息組成。
算法服務(wù)器會啟動線程池同步的拿取就緒隊列中的組件并異步的處理組件服務(wù),對于Java語言實現(xiàn)的算法服務(wù),類加載器將組件服務(wù)源碼加載到JVM中,根據(jù)算法組件的信息實例化組件對象,封裝反射所需的參數(shù)來調(diào)用對應(yīng)的方法服務(wù)。對于MATLAB組件,采用命令行的形式封裝當(dāng)前組件的調(diào)用參數(shù)并運行組件算法。對于C++算法服務(wù)器,圖像處理部分借助于OpenCV,用戶借助其內(nèi)置函數(shù)進行圖像處理,也可以遍歷圖像的每一個像素點,除此之外還可以自己編寫圖像處理程序。對于Python算法服務(wù)器,借助于免費庫PIL輔助對算法組件進行處理。
在虛擬實驗平臺的交互端,用戶根據(jù)實驗需要,選擇虛擬實驗儀器,通過連線創(chuàng)建實驗流程,這個過程的數(shù)據(jù)模型和操作面板的友好可用是影響用戶體驗的關(guān)鍵步驟。該平臺的實驗流程圖和組件列表樹都是通過JavaScript交互圖庫GoJS來實現(xiàn)的。GoJS是一種模型-視圖結(jié)構(gòu),視圖是模型的可視化,模型是視圖的數(shù)據(jù)體現(xiàn),模型的節(jié)點數(shù)組和連線數(shù)組跟視圖的節(jié)點模板和連線模板一一對應(yīng)。
圖3為客戶端實驗流程創(chuàng)建過程中視圖和數(shù)據(jù)的交互過程。進入新建實驗頁面時,瀏覽器會向Web端發(fā)送get請求,客戶端把返回的算法組件信息列表解析成菜單樹數(shù)據(jù)模型和可視化展示的菜單樹,同時會初始化一個實驗面板Diagram。選擇組件時,會在實驗面板中展示對應(yīng)的節(jié)點面板(NodeTemplates)同時在數(shù)據(jù)模型層的節(jié)點數(shù)組(NodeDataArray)中添加相應(yīng)的數(shù)據(jù)。添加連線時,會在實驗面板中展示對應(yīng)的連線面板(Link-Templates)同時會在數(shù)據(jù)模型層的連線數(shù)(LinkData-Array)添加連線的數(shù)據(jù)信息。用戶通過選擇算法組件,修改組件參數(shù)、添加連線創(chuàng)建一個完整的實驗流程圖。數(shù)據(jù)模型GraphLinksModel是客戶端跟Web應(yīng)用服務(wù)器進行交互的數(shù)據(jù)媒介,實驗面板Diagram則作為GraphLinksModel的可視化界面展示供用戶操作。
圖3 實驗前臺數(shù)據(jù)交互模型
客戶端的圖像模板與數(shù)據(jù)模型之間的交互保證了用戶操作的體驗,Web應(yīng)用服務(wù)器對數(shù)據(jù)的解析和對實驗持久化存儲則為調(diào)度集群鑒定了基石。對于客戶端傳來的數(shù)據(jù)模型,Web應(yīng)用服務(wù)端的控制層會根據(jù)連線對象,完善組件對象信息,例如組件對象A、B、C,存在A?B連線和A?C連線,完善A組件的nextNodeArr為B、C。
為了降低系統(tǒng)之間的耦合性,提高系統(tǒng)的健壯性,平臺將調(diào)度系統(tǒng)與Web應(yīng)用服務(wù)器進行了分離,它們通過持久層進行信息交互。調(diào)度服務(wù)器是實驗運行的核心環(huán)節(jié),合理的調(diào)度機制直接關(guān)系著整個平臺的并發(fā)能力。
數(shù)字圖像虛擬實驗平臺中,包含多種不同語言的異構(gòu)服務(wù)組件。這些組件之間在功能上相互獨立,用戶可以用連線將它們組合成一個有機整體。在設(shè)計得較為復(fù)雜的實驗流程中,組件之間的連接關(guān)系變得異常復(fù)雜,為了保證實驗有序高效地執(zhí)行,設(shè)計了一個合理的實驗運行調(diào)度機制。
一個完整的實驗流程,可以抽象為數(shù)據(jù)結(jié)構(gòu)里的有向圖。流程圖中的組件可以抽象為有向圖中的頂點,組件間的連接線可以抽象為有向圖中的邊,實驗中組件結(jié)果數(shù)據(jù)的流動方向與有向邊的方向一致。實驗的順利執(zhí)行需要嚴(yán)格按照組件的先后順序。從圖論上看實驗中組件的運行順序符合圖的拓撲排序順序,子節(jié)點的輸入?yún)?shù)依賴父節(jié)點的輸出參數(shù),即父節(jié)點的運行總是優(yōu)先于子節(jié)點的運行,值得注意的是實驗流程中不允許存在環(huán)以避免組件的無限循環(huán)運行。實驗中的組件流程按照圖的拓撲排序結(jié)果順序執(zhí)行,即可完成一次實驗調(diào)度。采用這種方式設(shè)計實驗運行調(diào)度機制,比較簡單,只需要先對實驗流程的抽象有向圖進行拓撲排序,然后逐個執(zhí)行組件。假設(shè)A、C、B是相互異構(gòu)的組件,A、B為C的父節(jié)點,A1、B1、C1分別是A、B、C節(jié)點對應(yīng)的服務(wù)端服務(wù)。按照拓撲排序調(diào)度方式,運行順序為A、B、C。調(diào)度系統(tǒng)執(zhí)行過程為:(1)調(diào)度服務(wù)器去注冊中心查詢A的服務(wù)地址A1,封裝服務(wù)接口需要的信息并遠程調(diào)用A1服務(wù),存儲A1服務(wù)結(jié)果到緩存。(2)調(diào)度服務(wù)器去注冊中心查詢B的服務(wù)地址B1,封裝服務(wù)接口需要的信息遠程調(diào)用B1服務(wù),存儲B1服務(wù)結(jié)果到緩存。(3)調(diào)度服務(wù)器去注冊中心查詢C的服務(wù)地址C1,根據(jù)A1和B1服務(wù)運行結(jié)果完善服務(wù)接口調(diào)用信息并遠程調(diào)用C1服務(wù),存儲C1服務(wù)結(jié)果作為C子節(jié)點的輸入?yún)?shù)。分析這個過程,調(diào)度服務(wù)器和服務(wù)集群中存在2N次數(shù)據(jù)傳輸,N為算法組件的個數(shù),很顯然A和B組件在執(zhí)行時是可以并發(fā)執(zhí)行而不存在先后順序。
為了減少數(shù)據(jù)傳輸次數(shù),保證系統(tǒng)的穩(wěn)定性,提高系統(tǒng)的并發(fā)性能,本文提出了一種新的調(diào)度機制,組件的運行順序不再嚴(yán)格地依賴拓撲排序的結(jié)果。如圖1所示,調(diào)度服務(wù)器負責(zé)與服務(wù)注冊中心和數(shù)據(jù)持久層進行交互,對實驗流程圖中各個組件的信息進行封裝,并將組件服務(wù)任務(wù)一次性下發(fā)到對應(yīng)的算法服務(wù)器上。調(diào)度服務(wù)器此時化身接收返回鏈路結(jié)果的服務(wù)端來與數(shù)據(jù)持久層交互。算法服務(wù)器用準(zhǔn)備隊列和就緒隊列用來存儲算法組件任務(wù),對于需要父類組件結(jié)果的組件任務(wù),會被插入到準(zhǔn)備隊列中,直到父類的參數(shù)到達方可移到就緒隊列中等待服務(wù)被調(diào)用。對上面的例子用這種模式處理過程如下:(1)調(diào)度服務(wù)器封裝A、B、C組件的參數(shù)信息,去注冊中心查詢組件服務(wù)地址A1、B1、C1,并遠程調(diào)用算法服務(wù)器的execute方法服務(wù),將組件任務(wù)分發(fā)到各自的服務(wù)器。(2)A和B組件參數(shù)就緒時被移到各自服務(wù)器上的就緒隊列等待服務(wù)的運行,運行結(jié)束后,根據(jù)組件nextNodeArr中存儲的next節(jié)點信息,調(diào)用C1服務(wù)器中fixParameter方法服務(wù)將處理結(jié)果傳遞給處于準(zhǔn)備隊列中的C組件。(3)C組件獲得父組件A和B傳來的結(jié)果,從準(zhǔn)備隊列轉(zhuǎn)到了就緒隊列等待服務(wù)運行。(4)如果C組件nextNodeArr中存儲的是end節(jié)點信息,C1服務(wù)器處理完C組件后會將結(jié)果傳遞給調(diào)度服務(wù)器,調(diào)度服務(wù)器將實驗結(jié)果持久化存儲,供Web服務(wù)器輪詢查詢結(jié)果并在客戶端可視化顯示,否則C組件繼續(xù)向下傳遞結(jié)果。在以上調(diào)度基礎(chǔ)上繼續(xù)優(yōu)化該模式,假設(shè)A、C的服務(wù)在同一臺算法服務(wù)器上,則把A、C組件視為一個調(diào)度集。A、C之間不需要將運行結(jié)果通過網(wǎng)絡(luò)傳輸,算法服務(wù)器處理時,對nextNodeArr中的next節(jié)點信息與當(dāng)前服務(wù)地址進行匹對。如果與當(dāng)前組件地址相同,則直接進行參數(shù)賦值,實驗創(chuàng)建到調(diào)度結(jié)束結(jié)果返回的時序圖,如圖4。
對以上兩種運行流程進行比較,可以看出對等模型相對于傳統(tǒng)模型的優(yōu)勢:(1)摒棄了傳統(tǒng)拓撲排序的完全順序執(zhí)行模式。當(dāng)多個組件同時處于就緒狀態(tài)時,可以并發(fā)執(zhí)行,類似于上例中的A、B組件,減少了實驗運行時間。(2)假設(shè)當(dāng)前實驗有M組相連組件在同一臺算法服務(wù)器上和N個剩余組件,按照傳統(tǒng)的拓撲排序模式網(wǎng)絡(luò)傳輸次數(shù)為。Ji表示第i組相連組件的個數(shù),當(dāng)前模型傳輸次數(shù)降低為N+M次。(3)可以異步返回獨立鏈路的實驗結(jié)果,一條鏈路出錯不影響另外一條鏈路正常運行。(4)與拓撲排序一樣,可以獲得實驗的鏈路運行路徑。(5)不需要結(jié)果緩存層對中間結(jié)果進行存儲,直接把運行結(jié)果傳遞給下一個組件。(6)圖中若存在多條鏈路,實驗內(nèi)部可以并發(fā)執(zhí)行,減少了實驗的運行時間,提高了實驗的容錯率。
多線程機制是確定Web應(yīng)用服務(wù)器、調(diào)度服務(wù)器和算法組件服務(wù)器高并發(fā)、高性能的關(guān)鍵。采用多線程可以使CPU在不同任務(wù)間不停切換,減少了CPU的空閑時間,降低了子任務(wù)平均等待的時間。但是在高并發(fā)系統(tǒng)中,頻繁的創(chuàng)建和銷毀線程不但浪費時間,而且降低系統(tǒng)運行效率。尤其在面向?qū)ο缶幊讨?,?chuàng)建線程對象要JVM分配相應(yīng)的堆棧內(nèi)存,運行前還要確保類被加載器加載到靜態(tài)存儲區(qū)。為了防止堆棧溢出,虛擬機會通過引用可達算法追蹤每一個對象的生命周期,確保能對銷毀的線程對象及時進行垃圾回收。除此之外,線程過多還會導(dǎo)致內(nèi)存溢出和線程間切換頻繁導(dǎo)致服務(wù)器崩潰。線程池通過限制最大線程數(shù)量和重復(fù)利用已創(chuàng)建的線程解決了以上問題,它將創(chuàng)建開銷分?jǐn)偟搅硕鄠€請求任務(wù)上,當(dāng)請求到達且有線程空閑時,該請求直接被處理,消除了創(chuàng)建線程的延遲,提高了響應(yīng)速度。
進程是系統(tǒng)資源分配的基本單位,進程的資源和地址空間同時被多個子線程共享。當(dāng)多個線程同時訪問某個資源時,存在資源同步問題。在調(diào)度服務(wù)器和算法服務(wù)器中,多個線程同時訪問臨界資源會產(chǎn)生寫丟失、臟數(shù)據(jù)等線程安全問題。例如調(diào)度服務(wù)器多個線程同時獲取數(shù)據(jù)存儲層處于等待運行狀態(tài)的實驗,算法服務(wù)器多個線程同時獲取就緒隊列待運行的組件。為了解決對臨界資源訪問的安全問題,平臺采用“序列化訪問資源”方法,通過給臨界資源代碼塊加鎖,確保臨界資源在同一時刻只有一個線程訪問。調(diào)度服務(wù)器則對獲取待運行實驗并更改實驗狀態(tài)這個過程加鎖。算法服務(wù)器中,對獲取待運行組件并更改組件狀態(tài)這個過程加鎖,實現(xiàn)了對臨界資源的互斥訪問。
圖4 算法調(diào)度時序圖
線程池數(shù)量設(shè)置過小不能充分利用服務(wù)器資源,設(shè)置過大則會造成線程上下文頻繁切換甚至?xí)捎谡加孟到y(tǒng)資源過多導(dǎo)致服務(wù)器宕機,合理的線程數(shù)目是確保系統(tǒng)高并發(fā)運行的基礎(chǔ)。經(jīng)過調(diào)研分析得:對于CPU密集型應(yīng)用,線程池大小一般設(shè)置為N+1,對于IO密集型應(yīng)用,線程池大小一般設(shè)置為2N+1,N為CPU的核數(shù)。目前數(shù)字圖像處理平臺服務(wù)器機器的CPU都是8核,為了得到調(diào)度的最佳線程數(shù)量,對調(diào)度系統(tǒng)線程池大小用二分法進行性能測試,測試區(qū)間值為10~25個,經(jīng)過分析得線程池的最佳大小配置之一為20個,初始化4組scheduledExecutorTasks,首次執(zhí)行分別延時0.5 s、1 s、1.5 s、2.0 s,之后采用非固定間隔每隔3 s定期啟動線程處理實驗任務(wù),直到線程數(shù)量達到20。
平臺中的Thrift服務(wù)使用非堵塞I/O模型作為多線程服務(wù)器端來處理大量并發(fā)連接請求。如圖5所示,AcceptThread線程對象來監(jiān)聽socket上的新連接,負載均衡器決定將請求分配給哪個SelectorThread對象,SelectorThread對象處理網(wǎng)絡(luò)I/O操作,同時把具體的調(diào)用執(zhí)行交給ExecutorService線程池中的線程。這種模式下,線程AcceptThread處理連接請求確保了能夠及時對大量并發(fā)連接請求做出響應(yīng),除此之外,以將網(wǎng)絡(luò)I/O分散到多個SelectorThread線程的方式加速了網(wǎng)絡(luò)I/O的讀寫操作。
圖5 Thrift服務(wù)端工作模式
總體而言,虛擬實驗平臺采用了同步代碼塊和線程池的技術(shù)保證了系統(tǒng)的高可用和高并發(fā)。
根據(jù)前面提到的系統(tǒng)架構(gòu)和關(guān)鍵技術(shù),實現(xiàn)了面向異構(gòu)資源集成的數(shù)字圖像虛擬實驗室平臺。該平臺公共組件庫包含了多種語言(MATLAB、Java、C++和Python等)實現(xiàn)的常用的數(shù)字圖像處理算法,例如灰度變換、繪制直方圖、空間濾波、頻率濾波、邊緣檢測和傅里葉變換等數(shù)百種算法。除了系統(tǒng)的公共組件外,用戶也可以把用自己熟悉語言開發(fā)的組件集成到平臺中,通過異構(gòu)組件發(fā)布的方式發(fā)布為Web服務(wù)組件,提高組件的復(fù)用性。
圖6給出了創(chuàng)建實驗的界面,菜單欄顯示了當(dāng)前用戶的功能模塊,左側(cè)面板是組件列表,包含基本輸入、輸出組件、公共組件和用戶組件。公共組件和用戶組件下面又包含了MATLAB、Java、C++、Python組件的子目錄,左下角面板顯示當(dāng)前組件的描述信息,中間面板是實驗流程搭建面板,右邊側(cè)欄是組件屬性參數(shù)配置欄。以搭建“通過圖像灰度變換與空間濾波來模擬空間域圖像增強”實驗為例,首先根據(jù)個性化流程在組件列表欄選擇需要的組件:輸入圖像組件imread,結(jié)果顯示組件imshow,灰度變換組件Rgbtogray(Java),中值濾波組件Medfilter(MATLAB),繪制直方圖組件ImageHist(MATLAB),均值濾波組件Avgfilter(C++)和椒鹽加噪組件AddSaltpeppernoise(Python)。然后按照實驗流程連接組件,用戶可以更改流程圖中組件的名稱。調(diào)節(jié)椒鹽加噪組件的參數(shù)density和均值濾波組件的參數(shù)hsize。默認(rèn)density參數(shù)為0.5,hsize參數(shù)為2。
圖6 空間域圖像增強實驗
圖7 展示了實驗運行路徑和結(jié)果,點擊實驗結(jié)果圖片可以查看原圖。
圖7 空間域圖像增強實驗結(jié)果
平臺采取分布式調(diào)度策略[12-14]完成對高并發(fā)實驗的處理,系統(tǒng)可以根據(jù)需要設(shè)置多個調(diào)度服務(wù)器,平臺為管理員提供了實驗調(diào)度監(jiān)控視圖,管理員可以看到整體調(diào)度集群的調(diào)度統(tǒng)計結(jié)果,并能選擇時間段直觀地查看實驗運行過程,包括實驗的提交時間、運行時間、結(jié)束時間和實驗運行狀態(tài)信息。
為了保證系統(tǒng)的高效可用,對其中一個調(diào)度服務(wù)器調(diào)度實驗進行了統(tǒng)計。測試實例中,處于waiting-Running待運行狀態(tài)的實驗有740個,平均每個實驗包含12個組件,實驗的輸入圖片大小為500 KB,每個組件的運行時間約為1 s,一個實驗的運行時間平均12 s,調(diào)度服務(wù)器CPU核數(shù)為8個,內(nèi)存8 GB,設(shè)置線程池的最大值為20。對單個實驗調(diào)度的開始和結(jié)束時間進行了可視化統(tǒng)計展示,開始時間呈上升趨勢,反映了調(diào)度服務(wù)器同步獲取數(shù)據(jù)存儲層的數(shù)據(jù),多線程并發(fā)異步運行待運行的實驗。根據(jù)調(diào)度理想時間(min)計算公式得750個實驗的理想運行時間為7.4 min,得出實際實驗調(diào)度間隔時間為8 min。中間同步獲取數(shù)據(jù)和算法服務(wù)器間通信的網(wǎng)絡(luò)傳輸代價是時間誤差的主要來源,屬于有效誤差。
本文設(shè)計的實驗平臺非常靈活,除了數(shù)字圖像處理課程還可以用于其他算法設(shè)計類課程的實現(xiàn),如數(shù)字信號處理、密碼學(xué)、機器學(xué)習(xí)等。
總之,本文在解決了算法構(gòu)件化、跨編程語言調(diào)用和調(diào)度優(yōu)化等關(guān)鍵技術(shù)問題的基礎(chǔ)上,設(shè)計并實現(xiàn)了一個能集成多種編程語言的實驗平臺,為數(shù)字圖像處理課程提供了完整的實驗環(huán)境。