前一節裡面簡單介紹了資料訪問優化的幾種方式,接下來詳解介紹一下:
1.datamotion network:
fpga
的資料傳輸網路是用來連線程式執行在
ps端和
pl端。
sdsoc
環境將會自動的建立乙個基於資料型別的資料傳輸網路,但是我們可以使用指令來優化執行速率和硬體資源。
常規的資料傳輸型別有: (
1)scalar:
常量經常通過
axi_lite
協議傳輸。 (
2)array:
陣列包含多個資料值,並且可有效的使用高速
dma傳輸協議。
sdsoc
環境提供了許多選項來控制硬體和資源的有效性,甚至允許特定的傳輸資料格式來應用在硬體上。 (
3)pointers:
預設情況下,如果沒有任何語法,乙個指標引數被當作乙個常量處理。如果乙個指標多次寫入或者讀出,語法上應該保證資料傳輸的高效性。 (
4)strector class:
結構體和類
2.memoryallocation/
sdslib
分配連續的記憶體位址)
sdsoc
編譯器將會分析你的程式,進而選擇乙個合適的資料型別用於在軟體和硬體上使用,資料的型別會根據負載的大小,加速器上的硬體介面和函式引數的屬性而決定。當編譯器可以保證乙個陣列引數位於連續的實體地址上時,它就可以使用最有效的資料傳輸。使用
sds_lib
函式庫來分配資料或者記憶體對映陣列時,可以確保編譯器讓記憶體訪問使用連續的位址。
eg. 1
)sds_alloc(size_tsize);//
使用連續的位址分配記憶體;使用
axi_dma_******
傳輸,該協議在連續位址傳輸上更快。 2
)malloc
:作為自由變數分配在棧。有助於
sdsoc
編譯器選擇最佳的資料發;非連續分配記憶體;使用
axi_dma_sg傳輸
當然有可能由於程式結構的原因,
sdscc
warning:[dmanalysis83-4492]unable to determine the memory attributes passed to>.......
這時候你可以在需要連續分配位址的程式上加上一下**來盡量是的資料分配是連續的(注意:這個函式並不一定確保是的資料分配是連續的,你必須還的
sds_alloc
來分配記憶體資料)
其實在具體資料記憶體分配中,使用的是一下指令: 3
)#pragmasds datamem_attribute(a:physical_contiguous)//
預設實體地址是非連續的。在函式宣告前必須使用該指令。
該指令的引數中有:
physical_contiguous
arrayname
被分配使用
sds_alloc
;連續分配記憶體;使用
axi_dma_******
傳輸,該協議在連續位址傳輸上更快。
non_physical_contiguous
arrayname
是使用malloc
或作為自由變數分配在棧。有助於
sdsoc
編譯器選擇最佳的資料發;非連續分配記憶體;使用
axi_dma_sg
傳輸。 3.
(1)通常情況下,硬體函式呼叫,涉及到函式引數的輸入輸出的複製。利用乙個共享的記憶體模型對於硬體函式的引數而言是可行的,但是需要主要注意的是,在吞吐量**式的傳輸下,從
pl埠訪問外部
ddr的延時會明顯高於
cpu訪問外部
ddr(cpu
頻率高得多原因?)。
sdsoc
環境通過插入一下函式來宣告共享記憶體:
#pragmasds data zero_copy(a[0:])//
零拷貝
(2)對於可綜合的硬體功能,從共享記憶體(使用
zero_copy
函式)讀取
/寫入單個資料通常是低效率的。乙個更有效的辦法是採用
memcpy
從記憶體中爆發式地讀
/寫資料,並且將資料儲存在本地記憶體中。(先從外地訪問,然後再儲存在片上快取。)
(3)指定資料傳輸型別
對於複製和零拷貝(記憶體共享)記憶體語義,另乙個有效的替代辦法是在
pl和片外的
ddr中傳輸資料,用於記憶體效率最大化。每當你需要非時序的硬體功能,可以使用硬體函式在本地記憶體中儲存資料,用於重複訪問變數。(應用
plfpga
sdscc
編譯器通過硬體函式來允許資料流訪問(也就是說,指定索引順序後,每個元素將精確地被訪問一次。)插入一下函式來立即指定函式的原型。
#pragmasds data access_pattern(a:sequential)//access pattern
,指定傳輸型別
=sequential| random
該指令的引數為:
sequential
:資料以流的方式訪問輸,編譯器會生成乙個
streaminginte***ce
(比如fiffo)
random
:使用ram
來訪問資料
對於陣列作為指標型別傳輸給硬體函式,有時候編譯器可以推斷傳輸的大小,如果不能夠推斷的話,編譯器會給出一下資訊:
waring
:[dmanalysis83-4439]cannot determine data size for argument p of function foo
對此,使用以下特殊的資料傳輸長度:
#pragmasds data copy(a[0:l+2*t/3])//scalar arguments l,t to same function
其中需要注意的是同乙個資料物件不能夠同時使用
zero_copy
和copy. (
5)copy
和zero_copy
區別:
copy
指令:將資料在
cpu處理器和硬體函式上傳輸
zero_ copy
指令:硬體函式通過
axi匯流排訪問共享資料
#pragmasds data copy(p[0:array_size]) *p;
引數[: ]
引數跟據編譯器能否推斷陣列傳輸的長度,不能推斷的話,需要自己宣告,如果沒有指定長度的話,編譯器會跟據資料傳輸情況判定傳輸的長度。
在每個函式的呼叫基礎上,你可以改變改變資料的傳輸長度,以避免硬體函式在函式定義中不需要通過設定陣列的長度(也就是說,函式引數都應該指明所有的變數大小)
4.datacache coherency/
ps埠訪問)
對於每乙個由系統要求的傳輸資料,
sdscc/sds++
編譯器自動生成生成軟體配置**。系統預設的假設是保持在
cpu和硬體函式之間的記憶體訪問是一致的。
為了使得記憶體訪問一致性,編譯器可以在傳輸資料到硬體函式之前執行快取重新整理,並將資料從硬體函式傳輸到記憶體之前執行快取失效。(執行快取重新整理,將原始的快取失效,以免新來的資料等待???)(預設操作)
上面的操作的正確性是必要的,但是有時候會影響應用的效能。當你使用
zynqdevece hpports
時,當你知道
cpu不訪問記憶體(應用程式的正確性不依賴快取記憶體一致性),你可以重寫以上預設。這樣做可以避免不必要的快取重新整理開銷。使用一下
api來分配記憶體:
void*sds_alloc_non_cacheable(size_t size) pl
訪問,不由
cpu訪問。
5data access patters/
資料訪問模式()
由於fpga
的優越性能,
fpga
被選中來實現
c**。乙個
fpga
的大規模並行架構允許它執行的操作比乙個
cpu處理器的固有的順序操作的速度更快。使用者通常都希望利用這一效能。
這裡的重點理解是理解
c**中固有的訪問模式對結果可能產生的影響。雖然最受關注的是那些進入和推出硬體功能的訪問模式,但在硬體功能中的任何瓶頸都會對函式的訪問速率產生負面影響,因此考慮函式內的訪問模式也是值得考慮的。
為了突出強調某些資料訪問模式如何對效能產生負面影響,並演示如何使用其他模式來完全支援
fpga
的並行性和高效能功能,將在下一節中通過一種影象卷積演算法來闡述。
Javascript效能優化(二) 資料訪問優化
資料的儲存位置,關係到 執行時資料被檢索到的速度,js中有四種資料儲存位置 直接量 變數 陣列 物件。其中直接量可能比較少聽說,其實可以理解為表示匿名函式 匿名物件的乙個變數,如var sum function a,b sum就是乙個函式直接量。四種資料儲存位置中,直接量和區域性變數的訪問效能微不足...
效能調優 nginx優化
nginx是乙個高效能的web和反向 伺服器,有很多優越的特性。在高併發的情況下nginx的一些預設引數並不適用。下面介紹一下nginx優化的幾個方面 1.配置執行緒數和併發數 worker processes 4 cpu 程序數 events2.配置後端server的長連線 upstream se...
(遊戲執行效能)優化
當基本遊戲功能到位時,就要確保遊戲執行表現能夠達標。我們衡量遊戲執行表現的乙個基本工具是unity內建分析器以及xcode分析工具。使用unity分析器來分析裝置上的執行 真是一項寶貴的功能。我們總結了這種為將目標裝置的幀率控制在60fps而進行衡量 調整 再衡量過程的中相關經驗。一 遇到麻煩時要呼...