[英]CUDA An algorithm to partition an array into blocks based on sum of elements
這里是問題:我有一個包含隨機數的數組。 我應該將它們划分為多個塊,以便在每個塊中,所有元素的總和不大於給定N。有效地解決
因此,例如,我嘗試如下: N=8
,數組為:
{2, 3, 1, 4, 4, 1, 6}
執行包含和掃描:
{2, 5, 6, 10, 14, 15, 21}
然后將其簡單地除以N=8
,得到以下分區:
{0, 0, 0, 1, 1, 1, 2}
然后我意識到存在一個錯誤,第二個塊中所有元素的總和是4+4+1=9
而不是8
,因為通過使用整數除法,我假設第一個塊中所有元素的總和為成為8。
正確的分區應該是:
{0, 0, 0, 1, 1, 2, 2}
我試圖遍歷列表並重新划分邊界點,但是並行實現比串行實現慢。 您是否碰巧知道解決此問題的有效並行算法?
從並行計算開始,而不是從掃描開始,首先為每個節點n(i)計算下一個節點n(j)的索引,該索引得出一個從n(i)開始且總和小於或等於8的子序列。 。 (第1步)
這是每個線程並行操作的相當短的循環,它將為您提供一系列索引。
{2,3,1,4,4,1,6}
{2、3、3、4、5、6、6}(步驟1結束)
然后並行遍歷從節點0開始的鏈表; 考慮在步驟1中為0計算的索引之后的節點為0的后繼節點;基本上,這是解決方案中bin起點的鏈接列表。
[在log(n)個步驟和n個log(n)中並行計算一個矩陣,該矩陣在位置(i,k)處為節點i提供了距離節點i 2跳躍點的節點。
{0,1,2,3,4,5,6}
3,4,4,5,6,---
5,6,6,-,-,-,-
-,-,-,-,-,-,-
從節點0開始並行計算每個節點的位置,並依次喚醒更多節點以進行log(n)總體並行步驟。
0, - , - , - 1, - 2, -
分散並獲取起點列表](步驟2)
{0,3,5}
現在從該序列並行散布一個新的0和1序列,如下所示; 從0開始。(第3步)
{0,0,0,1,0,1,0}
最后應用全面掃描以獲得您的結果。 (第四步)
在您的示例中:
{2,3,1,4,4,1,6}
{2、3、3、4、5、6、6}(步驟1)
{0,3,5}(步驟2)
{0,0,0,1,0,1,0}(步驟3)
{0,0,0,1,1,2,2}(步驟4)
如果原始序列中沒有0,則initail循環具有恆定的步長和線性工作量,因此您需要進行遍歷為log(n)步和掃描的列表遍歷。 如果原始序列中有零,但數字是隨機選擇的自然數,則具有多個長零序列會在受影響的SM上造成最壞情況的可能性仍然很低。 只要自然數是隨機選擇的,那么大於8的常數就不會有太大區別。 實際上,出於類似的原因,將8作為輸入的一部分也不應該是一個問題。
如果涉及負數,則此解決方案不可行,但可能會朝着改進的常規解決方案邁出一步。
我可以看到有一個更簡單的解決方案的空間,我整理了一些已知的構件。 據我所知,該解決方案仍然是正確且切實可行的,使用了已知的模式,而且至少我們知道有一個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.