划分设计技术
均匀划分技术
Case1:并行归并排序
对n个元素A[1…n]排序,则将A均匀分为p组,其中p为处理器个数,按如下过程排序:
-
均匀划分:将A均匀划分为p段,并分配给对应处理器。
-
局部排序:处理器pi对本地数据排序
-
选取样本:pi从本地选取p个样本元素(一般为等距采样)。
-
样本排序:使用一台处理器对 p 2 p^2 p2个样本进行排序。
-
选择主元:使用一台处理器在 p 2 p^2 p2个样本中选取p-1个主元(等距采样),并广播给所有处理器。
-
主元划分:pi对本地数据根据p-1个主元划分为p段。
-
全局交换:各处理器将划分的第i段交换到pi处理器中
-
归并排序:pi对本地数据进行排序,最终由所有处理器中的数据按照 p 1 , . . . , p p p_1,...,p_p p1,...,pp的顺序归并即为排列好的数组。。
方根划分
Case2:归并算法(Valiant归并)
对长度为p,q的有序数组A和B归并,则将A均匀分为 p \sqrt{p} p组,每组有 p \sqrt{p} p个元素,将B划分为 q \sqrt{q} q组,每组 q \sqrt{q} q个元素,按如下过程排序:
-
方根划分:按照方根对A,B划分,并确定划分元( n − 1 \sqrt{n}-1 n−1个划分元)。
-
段间比较:A划分元与B划分比较(包括B的最后一个元素),确定每一段插入的位置。
-
段内比较:A划分元在上一步找到的对应B段内找到适当位置插入。
-
递归归并:B按照A插入的划分元重新划分,则B中两划分元 p i , p i + 1 p_i,p_{i+1} pi,pi+1间的段和A最初被此两个划分元划分的段值域相同,两两一组递归执行归并算法。
归并算法最多需要 p q \sqrt{pq} pq个处理器,且每次递归时数组规模为之前的根号级别,即规模呈指数递减,最多迭代loglogp层,因此算法复杂度为 O ( l o g l o g p ) , p ≤ q O(loglogp),p\leq q O(loglogp),p≤q
对数划分
并行归并
对数划分的并行归并和平方划分类似,通过将B划分为长度为 l o g ( q ) log(q) log(q)大小的段并将A对应分段,递归归并完成。
分治设计技术
分治设计基本步骤
- 将输入划分为若干规模相等的子问题
- 并行递归求解子问题
- 并行归并子问题的解,获得原问题的解
与划分的主要区别为划分重点在原问题的划分方法上,而分治则主要考虑子问题计算结果的归并。
Case3:双调归并网络
双调序列即先增后减或先减后增的序列,或通过循环可以获得上述性质的序列。双调归并即输入一个双调序列,X,输出非降(增)有序数列Y。
Batcher定理:对于i和i+n/2组成的n/2对元素,其最大值/最小值组成的序列s/l仍为双调序列,且 ∀ i , j ∈ r a n g e ( 0 , n / 2 ) , s i ≤ l j \forall i,j\in range(0,n/2), s_i\leq l_j ∀i,j∈range(0,n/2),si≤lj
Batcher双调归并算法步骤如下:
-
根据Batcher定理,使用n/2个处理器,并行将X分解为两个双调序列s和l,其中:
- s i = m i n { x i , x i + n / 2 } s_i=min\{x_i,x_{i+n/2}\} si=min{xi,xi+n/2}
- l i = m a x { x i , x i + n / 2 } l_i=max\{x_i,x_{i+n/2}\} li=max{xi,xi+n/2}
-
递归划分 s , l s,l s,l,最终按照s,l顺序合并两序列即可。
在实际应用中,双调归并可以直接由硬件通过简单逻辑门实现,如下图:
平衡树设计技术
Case4:计算前缀和
经典算法,有点类似线段树的思想,一张图即可看懂:
两次传递,时间复杂度为 O ( l o g n ) O(logn) O(logn)
倍增设计技术
又称指针跳跃(pointer jumping)技术,特别适合于处理 链表或有向树之类的数据结构。当递归调用时,所要处理数据之间的距离逐步加倍, 经过k步后即可完成距离为2k的所有数据的计算。
Case5:表序问题
给定单向链表L,计算每个节点在链表中的位置。
算法如下(每个节点分配一个处理器,循环后设立全局障):
- 初始化:为每个节点分配一个指针
P
k
=
n
e
x
t
(
k
)
P_k=next(k)
Pk=next(k),并行初始化所有节点distance:
- if P ( k ) = k P(k)=k P(k)=k distance(k)=0
- else distance(k)=1
- 重复下列操作logn次
- if P(k)!=P(P(k))
- distance(k)=distance(k)+distance(P(k)), P(k)=P(P(k))
- rank(k)=distance(k)
- if P(k)!=P(P(k))
即按照指数增长步长,直到达到链表尾,此算法时间复杂度为 O ( l o g n ) O(logn) O(logn)(计算前缀和也有类似算法)
Case6:求根节点
和表序问题类似,每次迭代中更新指针指向父节点的父节点,时间复杂度为 O ( l o g n ) O(logn) O(logn)
流水线设计技术
将算法流程划分成p个前后衔接的任务片断,每个任 务片断的输出作为下一个任务片断的输入。所有任务片断按同样的速率产生出结果。
Case7:DFT计算(脉动算法,Systolic algorithm)
由于DFT核矩阵的特殊性,可以使用秦九韶算法将其分解为序列运算:
因此可以利用流水线逐层并行计算,即上级的计算结果作为下级的宿儒。