劉士謙
(廣州海格通信集團股份有限公司,廣東 廣州 510663)
隨著5G技術的日益成熟和廣泛應用,人們正高速地邁入一個手機、可穿戴設備乃至智能家用電器等設備都能夠實現(xiàn)彼此互聯(lián),并產(chǎn)生海量信息交互數(shù)據(jù)的數(shù)字化世界。面對海量信息數(shù)據(jù)的大量涌現(xiàn),圖形處理器GPU憑借其極強的并行計算處理能力,代替數(shù)字信號處理器DSP組成GPU+CPU架構的平臺。該架構平臺為現(xiàn)代無線接入網(wǎng)設備的信號處理提供了一種理想的技術手段。在GPU+CPU平臺架構中,如何有效地跟蹤調試GPU的運行信息,成為GPU程序開發(fā)中必須解決的一個問題。
當前計算機處理器主要分為中央處理器CPU和圖形處理器GPU兩大類。在傳統(tǒng)的計算機架構中,GPU只負責圖形渲染,大部分的處理都交由CPU完成。
由于圖形渲染的高度并行性,使得GPU可以通過增加并行處理單元和存儲器控制單元的方式來提高運算處理能力和存儲器帶寬。相對于CPU而言,它將更多的晶體管用作執(zhí)行單元,從而大大地提高了計算能力。從而令GPU在處理能力和存儲帶寬上相對CPU有著非常明顯的優(yōu)勢,在成本和功耗上也不需要付出太大的代價,為提升計算速度、計算能力提供了新的解決方案[1]。
為了推廣GPU的應用,英偉達公司于2007年推出了統(tǒng)一計算設備架構(Compute Unified Device Architecture,CUDA)這一易用編程接口。CUDA是C語言的一種擴展,集成了一些CUDA的內置應用編程接口,它允許使用標準的C語言來進行GPU代碼編程。編寫的代碼既適用于CPU,也適用于GPU[2]。
CUDA編程模型將CPU作為主機(Host),GPU作為設備處理器(Device)。Host和若干個Device協(xié)同工作,Host負責執(zhí)行控制部分以及串行運算;Device則專注于執(zhí)行高度線程化的并行處理部分。一旦確定了程序中的并行部分,就可以考慮把這部分的計算任務分配給Device來執(zhí)行,運行在Device上的CUDA并行計算函數(shù)稱為核函數(shù)(kernel),一個完整的CUDA程序由一系列的設備端kernel函數(shù)和主機端的串行處理部分共同組成。由于CUDA的易用性,已經(jīng)得到了很多硬件廠商的支持,正逐漸成為首個有可能發(fā)展成為GPU開發(fā)的候選編程語言[3]。
在GPU+CPU平臺架構中,跟蹤記錄GPU運行信息最恰當?shù)臅r間點是在CPU將相關數(shù)據(jù)交予GPU側進行運算處理時,對輸入及輸出的指令和數(shù)據(jù)進行實時的跟蹤記錄。為此,在設備CPU側的系統(tǒng)軟件中設計添加一個名為GPU Trace的功能模塊,用于記錄相關的GPU數(shù)據(jù)信息。由于在CPU側調用GPU進行運算處理的軟件功能模塊數(shù)量眾多,本GPU Trace模塊被設計劃分為server和client兩部分。其中server部分在設備啟動過程中,與其他的各個軟件功能模塊一同由啟動腳本先后創(chuàng)建運行;client部分則以動態(tài)庫的形式,提供用于跟蹤記錄GPU運行信息的接口。各個調用GPU進行運算處理的軟件功能模塊,通過調用client部分提供的函數(shù)接口,將需要記錄的GPU運行信息數(shù)據(jù)交由server部分進行統(tǒng)一的存儲記錄。
GPU Trace模塊server部分程序運行流程如圖1所示。當GPU Trace模塊中server部分在被創(chuàng)建,并完成對設備當前GPU Trace記錄的檢索后,阻塞等待由client發(fā)所送過來的帶有Trace數(shù)據(jù)句柄的消息。當server接收到帶有Trace數(shù)據(jù)句柄的消息,并通過句柄獲取到所需要的GPU Trace數(shù)據(jù)后,記錄Trace數(shù)據(jù)信息并更新相關的Trace信息描述記錄。
圖1 模塊server程序運行流程
為了確保記錄的實時性,GPU Trace功能模塊在內存中開辟了一塊存儲空間用以記錄GPU運行信息。該存儲空間由GPU Trace目錄和GPU Trace記錄數(shù)據(jù)兩部分組成。GPU Trace目錄部分,主要用于記錄存儲空間的內存地址、當前GPU Trace記錄序號、存儲空間使用情況等信息。GPU Trace記錄數(shù)據(jù)部分,除了GPU運行數(shù)據(jù)記錄之外,每一條Trace記錄的Record Head還記錄著Trace的序號、長度、是由哪個模塊申請,以及執(zhí)行Trace記錄操作的時間和代碼的位置。GPU Trace記錄數(shù)據(jù)部分采用循環(huán)的形式進行存儲,當存儲空間不足或耗盡時,新的GPU的運行記錄信息將會覆蓋最早的記錄信息。
在設備運行過程中,各個需要記錄GPU運行信息的軟件功能模塊,通過調用GPU Trace模塊中client端的GPU Trace函數(shù)向server端發(fā)送帶有Trace數(shù)據(jù)句柄的消息。該函數(shù)主要代碼如下:
cudaIpcGetMemHandle(&handle, (void *)devPtr);
msg.gpu_msg.handle=handle;
msg.gpu_msg.length=size;memcpy(msg.gpu_msg.module_tag, module_tag, 10);
snprintf(msg.gpu_msg.file, 20, "%s", filename(file));
msg.gpu_msg.line=line;msg_send(&msg, server_mbox, MSG_MY_MBOX);
GPU Trace模塊server端在接收到帶有Trace數(shù)據(jù)句柄的消息后,通過調用Fetch_GPU_Data函數(shù)獲得需 要記錄的GPU數(shù)據(jù)。然后將GPU數(shù)據(jù)與client端發(fā)送過來的Record Head信息,一同存儲到在內存中開辟的GPU Trace存儲空間中的GPU Trace記錄數(shù)據(jù)部分。Fetch_GPU_Data函數(shù)的主要代碼如下:
cudaIpcOpenMemHandle ( devPtr, Handle, cudaIpcMemLazyEnablePeerAccess);
cudaMemcpy ( buff, devPtr, length, cudaMemcpyDeviceToHost);
cudaIpcCloseMemHandle(devPtr);
本文基于CUDA編程接口,設計了一款GPU Trace模塊,實現(xiàn)了在GPU+CPU平臺架構中CPU側對GPU運行數(shù)據(jù)的獲取和記錄。該GPU Trace模塊為在采用GPU+CPU平臺架構的現(xiàn)代無線接入網(wǎng)設備中,跟蹤調試GPU的運行信息提供了一種實時高效的技術手段。