HLS 開發學習(七)排序

2021-10-08 06:26:41 字數 2920 閱讀 1890

歸併排序

學習自parallel programming for fpgas(the hls book)

大夥應該都很了解了,就是將乙個新的元素插入到乙個有序陣列中,並繼續保持有序。每步將乙個待排序的記錄,按其關鍵碼值的大小插入前面已經排序的檔案中適當位置上,直到全部插入完為止。

現在來考慮它的優化問題,基本**為

#include

"insertion_sort.h"

void

insertion_sort

(dtype a[size]

) a[j]

= item;

}}

最簡單的優化策略是使用pipeline指令,使其內部迴圈l2支援流水功能。

由於資料沒有相關性,設定期望流水線啟動間隔為1,即(#pragma hls pipeline ii=1)

目標:每個時鐘週期插入乙個新元素

#include

"insertion_sort_parallel.h"

#include

"assert.h"

void

insertion_sort_parallel

(dtype a[size]

, dtype b[size]

)else

if(j >

0&& b[j−1

]> item)

else

b[j]

= t;}}

}

本質上生成了多組內部迴圈體,這個內部迴圈體的結構主要是由幾個多路復用器、乙個決定誰最小的比較器和1個儲存陣列元素的暫存器等組成。當然,每個階段還可能包括緩衝暫存器,以確保生成的電路邏輯在乙個有效的時鐘頻率。若把內部迴圈體l2看為排序單元,那麼插入排序函式即是由乙個一維陣列的排序單元和一些在輸入輸出介面層的額外邏輯組成,在這種情況下, 外部迭代體僅需要size個時鐘週期就可以處理完。這個排序單元的主要特性是每個排序單元只與相鄰的排序單元通訊,而不是所有的單元。像這樣的設計被稱為脈動陣列,是一種常見的並行演算法優化的技術。在很多情況下,只要在不同的迴圈之間的通訊是有限的,當展開內部迴圈的優化,包括排序和脈動陣列的實現,都可以稱為隱式脈動陣列。

這塊其實我沒看懂啊,太草了

每個單元都是相同的,每個單元的輸入埠in用來接收當前暫存器中的值,較小的值傳送到輸出埠out, 而較大的值存放在本地暫存器local中, 其實每個單元的功能也就是out = min(in, local)。第i號單元的輸出結果傳遞給線性陣列的下乙個(即第i + 1號)單元的輸入,當新的輸入到來時,會與儲存在陣列中的本陣列進行比較,直到找到正確的位置。如果新的輸入大於陣列中的所有值,排序後的值將向右移動乙個單元陣列;如果新的輸入小於陣列中的所有值,此值會在陣列中傳輸,最終會被存放在最右邊的陣列單元中。當所有的資料都處理完時,最小的元素存放在第n − 1個陣列單元,直接從輸出讀出即可。

其中乙個單元的**為

void

cell0

(hls:

:stream

& in, hls:

:stream

& out)

else

}

輸入和輸出變數都宣告為hls的資料流型別。dtype是乙個型別引數,允許對不同型別進行操作。本地變數存放陣列中的某乙個元素,新增了static關鍵字是為了在多個函式呼叫中儲存它的值。這裡需要注意的是使用相同的函式,複製單元功能n次;每個單元必須有乙個單獨的單元靜態變數,乙個靜態變數不能跨n個函式共享。

歸併排序演算法的基本思想是將兩個有序序列合併成乙個較大的有序序列,可以在o(n)時間內完成。

核心思想是分治,學過的朋友應該都很熟悉了。

將兩個排序陣列組合成乙個較大的排序陣列的過程通常稱為two-finger演算法,two-finger操作初始化時指向每個陣列第乙個元素(數值in1中的元素3和陣列in2中的元素1),在演算法執行的過程中,兩個指標會指向陣列中的不同元素。

處理陣列排序大約需要nlogn次比較,以及額外的臨時儲存空間。

#include

"merge_sort.h"

#include

"assert.h"

// subarray1 is in[i1..i2-1], subarray2 is in[i2..i3-1], result is in out[i1..i3-1]

void

merge

(dtype in[size]

,int i1,

int i2,

int i3, dtype out[size]

)else}}

void

merge_sort

(dtype a[size]

)// copy temp back to a for next iteration

copy:

for(

int i =

0; i < size; i++)}

}

**裡首先考慮陣列中的每個元素作為乙個排序子陣列,外部迴圈的每次迭代都將排序子陣列合併成較大的排序子陣列。第一次迭代,對最大size為2的子陣列進行排序;第二次迭代,對最大size為4的子陣列進行排序;然後是8,以此類推。

啊啊啊啊啊啊啊啊啊啊啊啊啊啊好難啊但是最近好忙先放這裡了。

專題七 排序演算法

1 基本思想 每一趟從待排序的資料元素中選出最小 或最大 的乙個元素,順序放在待排序的數列的最前,直到全部待排序的資料元素排完。2 排序過程 示例 初 始 關鍵字 49 38 65 97 76 13 27 49 第一趟排序後 13 38 65 97 76 49 27 49 第二趟排序後 13 27 ...

資料結構複習之七 排序

重要參考資料 主要複製自這裡 一 排序的基本概念 穩定排序 如果排序表中有兩個相等元素,經過排序之後它們的相對位置不變,那麼這個演算法就是穩定的。二 插入排序 直接插入排序 插入排序是在乙個已經有序的小序列的基礎上,一次插入乙個元素。當然,剛開始這個有序的小序列只有1個元素,就是第乙個元素。比較是從...

c 編碼技巧 七 排序去重

var array new int array.sort array 對array排序遍歷輸出 foreach var item in array console.writeline item console.read 結果為 123 4567先轉化為list,再用自帶的list.sort 排序 v...