賽靈思SDAccel開(kāi)發(fā)環(huán)境為內存限制問(wèn)題提供優(yōu)化方法 作者: Jasmina Vasiljevic 多倫多大學(xué)研究員 vasilijev@eecg.toronto.edu Fernando Martinez Vallina博士 賽靈思公司軟件開(kāi)發(fā)經(jīng)理 vallina@xilinx.com 視頻流和下載通常會(huì )耗掉消費者絕大部分互聯(lián)網(wǎng)流量,同時(shí)也是云計算技術(shù)發(fā)展的主要推動(dòng)力。對視頻流和下載需求的持續增長(cháng),正在驅動(dòng)視頻處理應用邁出專(zhuān)業(yè)系統領(lǐng)域,步入數據中心。這一應用模式的轉變需要具備快速擴展能力的計算節點(diǎn)來(lái)滿(mǎn)足視頻內容制作和分發(fā)的各個(gè)不同高計算強度階段的需求,如轉碼需求和水印需求。 我們近期使用賽靈思SDAccel開(kāi)發(fā)環(huán)境來(lái)編譯和優(yōu)化專(zhuān)為FPGA加速卡采用OpenCL編寫(xiě)的視頻水印應用。視頻內容提供商使用水印起到廣告和內容保護的作用。我們的目的是設計一種能處理運行在A(yíng)lpha Data ADM-PCIE-7V3卡上,吞吐量為30fps,分辨率為1080p的高清(HD)視頻的水印應用。 SDAccel開(kāi)發(fā)環(huán)境能讓設計人員先用OpenCL編寫(xiě)應用,然后在無(wú)需了解底層FPGA實(shí)現工具的情況下把應用編譯到FPGA中?梢砸赃@種視頻水印應用為例來(lái)介紹SDAccel中的主要優(yōu)化技巧。 帶標識插入功能的視頻水印 該視頻水印算法的主要功能是在視頻流的特定位置覆蓋一個(gè)標識。用于水印的標識可以是活動(dòng)的,也可以是靜止的;顒(dòng)標識一般采用簡(jiǎn)短的重復性視頻片段來(lái)實(shí)現,靜止標識則采用靜止圖像。 廣播企業(yè)宣傳自己視頻流最常用的方法是把企業(yè)標識用作靜止水印,因此成為我們實(shí)例設計的目標。該應用根據下列等式,以逐像素粒度插入靜止標識。 ![]() 輸入和輸出幀為二維陣列,像素使用YCbCr色域表達。在該色域中,每個(gè)像素用三個(gè)分量表達。Y表示亮度分量,Cb表示色度藍色色差分量,Cr表示色度紅色色差分量。每個(gè)分量都用一個(gè)8位值表達,因為每個(gè)像素為24位。 該標識是一個(gè)包含待插入內容的二維圖像。掩膜也是一個(gè)圖像,但只包含標識的輪廓圖。掩膜的像素可以是白色或黑色。掩膜的白色像素表示標識的插入位置,黑色像素則表示原始像素未被觸及的地方。圖1所示的,就是這種視頻水印算法的運算方式實(shí)例。 目標系統和初始實(shí)現方案 我們運行該應用的系統如圖2所示。該系統由Alpha Data ADMPCIE-7V3卡組成,該卡通過(guò)PCIe®鏈路與x86處理器通信。在該系統中,主機處理器從磁盤(pán)提取輸入視頻流,將其傳輸到設備全局內存中。設備全局內存位于FPGA卡上,可供FPGA直接訪(fǎng)問(wèn)。除把視頻幀存放到設備全局內存中外,標識和掩膜也從主機傳輸到FPGA加速器卡上并存入片上內存中,以充分利用BRAM內存的低時(shí)延優(yōu)勢。因為本應用使用的是一個(gè)靜止標識,只需在片上內存中存儲靜止圖像和布局位置數據。 ![]() 圖1 - 工作中的視頻水印算法 ![]() 圖2 - 視頻水印應用系統總覽圖 創(chuàng )建數據后,主機處理器會(huì )給FPGA架構中的水印內核發(fā)送一個(gè)啟動(dòng)信號。該信號觸發(fā)內核完成三件工作:開(kāi)始從設備全局內存獲取輸入視頻幀;在掩膜定義的位置插入標識;將處理過(guò)的幀傳輸回設備全局處理器,等待處理器調用。 視頻流中每幀的數據傳輸與計算的協(xié)調工作使用圖3所示的代碼完成。 該代碼運行在主機處理器上,負責發(fā)送視頻幀到FPGA加速器卡,啟動(dòng)加速器,然后從FPGA加速器卡取回處理后的幀。 FPGA水印算法的首個(gè)實(shí)現方案如圖4所示。這是一個(gè)功能正確的應用實(shí)現方案,但沒(méi)有進(jìn)行任何性能優(yōu)化或為充分利用FPGA架構的功能進(jìn)行考慮。因此該代碼在SDAccel中編譯完成后,在A(yíng)lpha Data卡上運行得到的最大吞吐量?jì)H為0.5fps。 從圖4的代碼中可以看到,這種水印算法不是一種高計算強度的設計。大多數時(shí)間花在訪(fǎng)問(wèn)內存,讀取和寫(xiě)入視頻幀上。因此我們在優(yōu)化實(shí)例設計時(shí),把重點(diǎn)放在優(yōu)化內存帶寬上。 使用矢量化優(yōu)化內存訪(fǎng)問(wèn) 與其他軟件可編程架構相比,FPGA架構的優(yōu)勢之一在于靈活性強,能配置連接內存的總線(xiàn)。SDAccel能根據具體的應用內核創(chuàng )建用于連接內存的定制化數據路徑和架構。通過(guò)修改代碼,一次可以處理多個(gè)像素,從而能夠從內核中調用更高的內存帶寬。這個(gè)過(guò)程稱(chēng)之為矢量化。 矢量化的程度是否合適,取決于具體應用和所使用的FPGA加速器卡。以Alpha Data卡為例,設備全局內存接口寬度為512位,這與SDAccel為內核提供的最大AXI互聯(lián)寬度一致。鑒于最大帶寬為512位,該應用調整為每次處理20個(gè)像素(24位/像素×20像素=504位)。SDAccel完全支持矢量數據類(lèi)型。因此就本應用而言,代碼的矢量化非常簡(jiǎn)單,就是把所有陣列的數據類(lèi)型修改為char20(如圖5所示),這樣吞吐量就能達到12fps。 使用突發(fā)模式優(yōu)化內存訪(fǎng)問(wèn) 雖然矢量化能顯著(zhù)改善應用性能,但仍不足以實(shí)現30fps的吞吐量目標。該應用仍然受內存局限,因為內核每次只能向內存傳輸20個(gè)像素。為減輕內存限制對應用造成的影響,我們不得不修改內核代碼,以生成到內存的突發(fā)讀取/寫(xiě)入操作,從而實(shí)現大于20個(gè)像素的數據集。修改后的內核代碼見(jiàn)圖6。 代碼內核首先修改的是在內核中定義片上存儲,以便每次存儲像素塊。片上內存用內核代碼中聲明的陣列來(lái)定義。為啟動(dòng)到內存的突發(fā)事務(wù)處理,該代碼實(shí)例化memcpy命令,以將數據塊從DDR移到內核內的BRAM存儲系統中。根據片上內存資源的大小和待處理數據的量,一個(gè)視頻幀可分割成20個(gè)1920×54像素塊(如圖7所示)。 當memcry命令把數據塊放置到內核陣列中,該算法就會(huì )在數據塊上執行水印算法,然后把結果放回內核陣列。數據塊處理的結果隨后使用memcry命令傳送回DDR內存。反復執行這個(gè)操作20次,直至給定幀中所有的數據塊處理完畢。通過(guò)修改內核代碼,系統性能達到了38fps,超過(guò)了既定的30fps目標。 ![]() 圖3 - 用于協(xié)調每幀數據傳輸和計算的代碼 ![]() 圖4 - 水印內核的初始實(shí)現方案 ![]() 圖5 - 矢量化后的內核代碼 ![]() 圖6 - 針對突發(fā)數據傳輸優(yōu)化的內核代碼 應用前景廣泛 使用SDAccel開(kāi)發(fā)本文介紹的這類(lèi)應用時(shí)所進(jìn)行的必要優(yōu)化屬于軟件優(yōu)化。因此這些優(yōu)化工作與從其他處理架構中(如GPU)獲取性能所開(kāi)展的優(yōu)化類(lèi)似。使用SDAccel后,讓PCIe鏈路工作、驅動(dòng)程序、IP布局和互聯(lián)等細節都不是問(wèn)題,使我們就像設計人員一樣只需集中精力開(kāi)發(fā)目標應用。 我們在水印應用中所做的優(yōu)化適用于使用SDAccel編譯過(guò)的所有應用。事實(shí)上視頻水印應用就是一個(gè)很棒的技巧講解案例,詳細介紹了賽靈思SDAccel中推出的優(yōu)化方法。 ![]() 圖7 - 把視頻幀分區成數據塊 |