并行算法笔记(二)——并行算法设计

串行算法的直接并行

最直接,最易于理解的设计方法,发掘和利用现有串行算法中的并行性,直接将串行算法改造为并行算法。

Case 1:快速排序

​ 快速排序的串行算法思想为随机选取主元进行划分,之后递归排序。直接并行化思路即每次划分后将子任务分配给新的处理器。不过由于划分操作还是由单个处理器串行执行的,因此平均时间复杂度为 T ( n ) = T ( n / 2 ) + n = O ( n ) T(n)=T(n/2)+n=O(n) T(n)=T(n/2)+n=O(n)

​ 为了使Partition可以并行处理,重新考虑归并排序:划分操作可以看做是构造一个二叉树结构。选取的主元即为子树的根节点,且左子树小于右子树,因此可以将每个处理器看作一个节点,保存着A[i]的数值。

​ 引入新的数组LC[1…n]和RC[1…n],其中LC[i]和RC[i]分别表示第i个处理器的左右子树根节点,这样n个处理器即构成一个二叉树。并且每个处理器保存父节点在LC的下标fi。初始时,设置第一个处理器的值为根节点,并通知所有处理器。在接下来的每轮中:

  • 如果自己的值小于等于父节点,则应该在左子树中,将自己的下标填入LC[fi]中,直到所有左子树的节点都完成上述操作。此时最后一个填写的处理器i即被选为划分依据,该处理器退出计算,其余所有节点都将i更新为自己的父节点。
  • 如果自己的值大于父节点的值,则应该在右子树中,将自己的下标填入RC[fi]中,更新父节点。

伪代码如下:

Repeat for each processor i!=root do
if(A[i]<A[fi] or A[i]=A[fi] and i<fi) then
	LC[fi]=i
	wait()
	if(i=LC[fi])
		exit
	else
		fi=LC[fi]
	endif
else
	RC[fi]=i
	wait()
	if(i=RC[fi])
		exit
	else
		fi=RC[fi]
	endif
EndReqeat

在算法执行后,根据LC和RC即可构造出一棵二叉树,通过前序遍历即可完成排序。此算法每一层树的构造用时为 O ( 1 ) O(1) O(1),平均树高为 O ( l o g n ) O(logn) O(logn),因此平均时间复杂度为 O ( l o g n ) O(logn) O(logn),最坏情况时树高为n,时间复杂度为 O ( n ) O(n) O(n)

Case2:枚举排序

​ 枚举排序为最简单的排序算法,每个数通过一次遍历比较出有多少排在自己前面的数作为自己的下标,之后通过一次遍历利用下标排序。串行时间复杂度为 O ( n 2 ) O(n^2) O(n2)

​ 最直接的思维即为每个数并行的计算下标,这样每个数的时间开销为 O ( n ) O(n) O(n),并行算法时间复杂度为 O ( n ) O(n) O(n),由于每个处理器都需要读取整个数组,因此通讯复杂度为 O ( n 2 ) O(n^2) O(n2)

从问题描述开始设计算法

​ 即从问题本身描述出发,不考虑相应的串行算法,设计一个全新的并行算法。

Case1:串匹配算法

​ 串行算法中著名的串匹配算法是KMP算法,算法时间复杂度为 O ( m + n ) O(m+n) O(m+n)当模式串为常数级时算法具有线性时间复杂度。其核心思想为提前计算出next数组,记录当匹配失败时后移的长度,因此通过避免回溯去除了重复比较。

​ 不过KMP算法显然无法直接并行化,因此需要按照其思路重新设计算法。字符串是否具有周期性对后续算法的选择非常关键,因此首先对待匹配串P做周期性判断。定义失效见证函数(Witness Function)表征周期性,其定义如下:

  • 对于 j ( 1 ≤ j ≤ m / 2 ) j(1\leq j\leq m/2) j(1jm/2),如果 P [ j : m ] ≠ P [ 1 : m − j + 1 ] P[j:m]\neq P[1:m-j+1] P[j:m]̸=P[1:mj+1],则存在 w ( 1 ≤ w ≤ m − j + 1 ) , s = j − 1 + 2 , s . t . P ( w ) ≠ P ( s ) w(1\leq w\leq m-j+1),s=j-1+2,s.t.P(w)\neq P(s) w(1wmj+1),s=j1+2,s.t.P(w)̸=P(s),则WIT(j)=w。

  • 否则WIT(j)=0

显然当字符串不具有周期性时, W I T ( j ) ≠ 0 , 2 ≤ j ≤ m / 2 WIT(j)\neq0,2\leq j\leq m/2 WIT(j)̸=0,2jm/2

非周期算法举例

​ 按照指数次序,P分割为大小为 ( 2 1 , 2 2 , . . . ) (2^1,2^2,...) (21,22,...)的小块,并行和T的前缀匹配,淘汰失配的位置,最后对所有剩余位置进行全串T匹配。

借用已有算法求解新问题

矩阵乘法

​ 许多算法都需要矩阵乘法运算,这里记一下矩阵乘法的并行算法。待求矩阵 C = A B C=AB C=AB,其中B为列向量,则可通过分割矩阵A计算C:

A B = [ A 1 A 2 ⋮ A m ] B = ∑ A i B AB=\left[\begin{array}{ccc}A_1 \\A_2 \\ \vdots \\ A_m \end{array} \right ]B=\sum A_iB AB=A1A2AmB=AiB,其中 A i B A_iB AiB可并行计算。

​ 如果B不是列矩阵,同样可以通过列分解计算。

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值