精华内容
下载资源
问答
  • 是第三版《并行计算:结构•算法•编程(第3版)》是并行计算系列丛书之开篇,它以并行计算为主题,围绕并行计算机、并行算法和并行程序设计展开讨论,强调融并行计算机体系结构、数值与非数值并行算法设计以及并行程序...
  • 本书共二十章,包括基础篇4章,并行算法篇9章,数值并行算法设计篇3章,理论篇4章。
  • 最直接,最易于理解的设计方法,发掘和利用现有串行算法中的并行性,直接将串行算法改造为并行算法。 Case 1:快速排序 ​ 快速排序的串行算法思想为随机选取主元进行划分,之后递归排序。直接并行化思路即每次划分...

    串行算法的直接并行

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

    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不是列矩阵,同样可以通过列分解计算。

    展开全文
  • 每一次遇到问题和解决问题都是一种锻炼,一种尝试,从我们上并行计算课我懂得了很多电脑硬件和软件的知识,这些可能对于我们这个专业以后都是没有机会接触的,所以我觉得选择了并行计算与多核多线程技术这门课是非常...
  • 划分设计技术 均匀划分技术 Case1:并行归并排序 ​ 对n个元素A[1…n]排序,则将A均匀分为p组,其中p为处理器个数,按如下过程排序: 均匀划分:将A均匀划分为p段,并分配给对应处理器。 局部排序:处理器pi对...

    划分设计技术

    均匀划分技术

    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),pq

    对数划分

    并行归并

    对数划分的并行归并和平方划分类似,通过将B划分为长度为 l o g ( q ) log(q) log(q)大小的段并将A对应分段,递归归并完成。

    分治设计技术

    分治设计基本步骤

    1. 将输入划分为若干规模相等的子问题
    2. 并行递归求解子问题
    3. 并行归并子问题的解,获得原问题的解

    与划分的主要区别为划分重点在原问题的划分方法上,而分治则主要考虑子问题计算结果的归并。

    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,jrange(0,n/2),silj

    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)

    即按照指数增长步长,直到达到链表尾,此算法时间复杂度为 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核矩阵的特殊性,可以使用秦九韶算法将其分解为序列运算:

    在这里插入图片描述

    因此可以利用流水线逐层并行计算,即上级的计算结果作为下级的宿儒。

    展开全文
  • 并行最短路径算法Dijkstra。 为实现并行最短路径计算,我们必须要解决如下问题: (1)数据获取:利用随机函数生成大约2000个节点及其节点之间的距离。本程序使用邻接矩阵来存储带权有向图的信息。矩阵大小2000*2000...
  • 每一次遇到问题和解决问题都是一种锻炼,一种尝试,从我们上并行计算课我懂得了很多电脑硬件和软件的知识,这些可能对于我们这个专业以后都是没有机会接触的,所以我觉得选择了并行计算与多核多线程技术这门课是非常...
  • 我是如何进行异构并行计算算法设计的 我是如何进行异构并行计算算法设计的 文 / 刘文志 当2011年我从中科院毕业的时候,虽然已经成为了GPU并行计算领域小有名气的人物,但是我的心境非常不安,因为无论是在51job,...
  • 本书以并行计算为主题,主要讨论并行计算的硬件基础——当代并行计算机系统及其结构模型,并行计算的核心内容——并行算法设计与并行数值算法以及并行计算的软件支持——并行程序的设计原理与方法。本书强调融并行机...
  • 高性能期末并行计算期末考试复习提纲,主要是一些概念题、三个主要定律和三个编程题。
  • 通过对电网通讯结构的分析,确定了并行程序的设计方法,基于Matlab对并行计算机算法下的电网暂态过程进行数值模拟,结果表明,电网系统的电压、功率及转子角速度的变化幅度较小而且平稳,系统稳定性较高。
  • 本程序时利用mpi实现矩阵与向量并行相乘。你需要安装mpich并配置好环境。编译:mpicc Mat_vect_mult.c -o Mat_vect_mult 运行:mpirun -np 5 ./Mat_vect_mult ;5为进程数,可以更换
  • 目的 设计并实现一种基于数据划分的矩阵乘法的并行算法,将划分的数据交给多个线程同时执行,充分挖掘计算机的性能。方法 根据OpenMP并行编程的基本风格,并在visual Studio2005上搭建能够实现并行编程的环境平台。...
  • 一 . 运行环境VS2017 + MPI 二 . 算法原理可见博客...运行结果(dim = 600,cannon算法在问题规模较小的情况下仍能获得不错的加速比) 注:个人PC仅有8个计算核心,因而9核模拟的效果稍差

    一 . 运行环境VS2017 + MPI

    二 . 算法原理可见博客https://www.cnblogs.com/chihaoyuIsnotHere/p/10553617.html

    三.  使用到的MPI关键技术:虚拟笛卡尔进程拓扑

    四.  源代码:头文件Matrix.h与第三篇文章的类似,只需加上+号重载

    #include<iostream>
    #include"Matrix.h"
    #include<cmath>
    #include<ctime>
    #include"mpi.h"
    
    using namespace std;
    
    const int N = 600;
    int myid, numprocs,upRank,downRank,leftRank,rightRank,part,num;
    int masterNode;
    int coord[2];
    double start, finish;
    MPI_Comm Cart_Comm_World;
    
    int isqrt(int x)
    {
    	int ipart = sqrt(x);
    	if (ipart*ipart != x)
    		++ipart;
    	return ipart;
    }
    
    void MatrixScatter(Matrix &A)
    {
    	double *memoryPool = nullptr;
    	
    	if (coord[0] == 0 && coord[1] == 0)
    	{
    		Matrix tmp(N);
    		tmp.ranCreate();
    		//cout << tmp << endl;
    		memoryPool = new double[N*N];
    		
    		int count = 0;
    		for (int k = 0; k < part; ++k)
    			for (int h = 0; h < part; ++h)
    				for (int i = k * num; i <(k+1)*num; ++i)
    					for (int j = h * num; j < (h+1)*num; ++j)
    						memoryPool[count++] = tmp(i, j);
    	}
    	MPI_Scatter(memoryPool, num*num, MPI_DOUBLE, &A(0, 0), num*num, MPI_DOUBLE, masterNode, Cart_Comm_World);
    	
    	if (memoryPool)
    		delete[]memoryPool;
    
    }
    
    //进行初始位移
    void cannonInit(Matrix &A, Matrix &B)
    {
    	int x = coord[0], y = coord[1];//矩阵块的行号与列号
    	MPI_Status status;
    
            //获得当前矩阵块横坐标方向相聚x的左右邻居
    	MPI_Cart_shift(Cart_Comm_World, 1, x, &leftRank, &rightRank);
    	if (leftRank != myid)
    		MPI_Sendrecv_replace(&A(0, 0), num*num, MPI_DOUBLE, leftRank, 0, rightRank, 0, Cart_Comm_World, &status);
    	
    	MPI_Cart_shift(Cart_Comm_World, 0, y, &upRank, &downRank);
    	if (upRank != myid)
    		MPI_Sendrecv_replace(&B(0, 0), num*num, MPI_DOUBLE, upRank, 0, downRank, 0, Cart_Comm_World, &status);
    	
    
    }
    
    void cannonSolver(Matrix &A,Matrix &B)
    {
    	MPI_Cart_shift(Cart_Comm_World, 0, 1, &upRank, &downRank);
    	MPI_Cart_shift(Cart_Comm_World, 1, 1, &leftRank, &rightRank);
    	Matrix C(num);
    	MPI_Status status;
    	for (int i = 0; i < part; ++i)
    	{
    		C = C + A * B;
    		MPI_Sendrecv_replace(&A(0, 0), num*num, MPI_DOUBLE, leftRank, 0, rightRank, 0, Cart_Comm_World, &status);
    		MPI_Sendrecv_replace(&B(0, 0), num*num, MPI_DOUBLE, upRank, 0, downRank, 0, Cart_Comm_World, &status);
    	}
    	
    	double *memoryPool = nullptr;
    	if (myid == masterNode)
    		memoryPool = new double[N*N];
    	MPI_Gather(&C(0, 0), num*num, MPI_DOUBLE, memoryPool, num*num, MPI_DOUBLE, masterNode, Cart_Comm_World);
    	if (myid == masterNode)
    	{
    		Matrix result(N);
    		int count = 0;
    		for (int k = 0; k < part; ++k)
    			for (int h = 0; h < part; ++h)
    				for (int i = k * num; i < (k + 1)*num; ++i)
    					for (int j = h * num; j < (h + 1)*num; ++j)
    						result(i, j) = memoryPool[count++];
    		//cout << result << endl;
    		delete[]memoryPool;
    	}
    	
    
    
    }
    
    int main(int argc, char* argv[])
    {
    	MPI_Init(&argc, &argv);
    	
    	MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    
    
    	if (numprocs == 1)
    	{
    		
    		Matrix A(N), B(N);
    		A.ranCreate();
    		B.ranCreate();
    		start = MPI_Wtime();//随机数的生成特别耗费时间,不应该计入
    		Matrix result = A * B;
    		//cout << A * B << endl;
    		finish = MPI_Wtime();
    		cout << finish - start << endl;
    		MPI_Finalize();
    		
    		return 0;
    	}
    
    	
    
    	part = isqrt(numprocs);//一个维度的方向上,矩阵块数;isqrt是对整型的求根,保证不错
    	num = N / part;//分块矩阵的维度
    
            //创建虚拟笛卡尔拓扑,方便通信
    	int dims[2] = { part,part };
    	int periods[2] = { 1,1 };
    	MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, 1, &Cart_Comm_World);
    	MPI_Comm_rank(Cart_Comm_World, &myid);
    	MPI_Cart_coords(Cart_Comm_World, myid, 2, coord);
    	
    	int position[2] = { 0,0 };
    	MPI_Cart_rank(Cart_Comm_World, position, &masterNode);
    
    	Matrix A(num),B(num);
    	MatrixScatter(A);
    	
    	MatrixScatter(B);
    	start = MPI_Wtime();
    	cannonInit(A, B);
    	cannonSolver(A,B);
    	finish = MPI_Wtime();
    	if(myid == 0)
    	   cout << finish - start << endl;
    
    	MPI_Comm_free(&Cart_Comm_World);
    	MPI_Finalize();
    	return 0;
    }

    五.运行结果(dim = 600,cannon算法在问题规模较小的情况下仍能获得不错的加速比)

     注:个人PC仅有8个计算核心,因而9核模拟的效果稍差

     

    展开全文
  • 因此,研究并设计快速的串匹配算法具有重要的理论价值和实际意义。 串匹配问题实际上就是一种模式匹配问题,即在给定的文本串中找出与模式串匹配的子串的起始位置。最基本的串匹配问题是关键词匹配(Keyword ...
  • 随着计算机技术的进步,时域有限差分法(FiniteDifference TimeDomain)是一种求解电磁问题的数值计算技术,由K.S.Yee于1966年提出。他的基本思想是根据时域麦克斯韦方程的场分量微分式,用差分替代微分式,进行各场...
  • 研一开设的并行算法设计与分析,教材使用的是《并行算法的设计与分析 陈国良》,考试前进行总结如下: sdd

    研一开设的并行算法设计与分析,教材使用的是《并行算法的设计与分析 陈国良》,考试前进行总结如下:

    考试内容如下:
    在这里插入图片描述

    展开全文
  • 基于并行算法的快速人脸识别系统设计与实现.pdf
  • 并行计算及并行算法

    万次阅读 多人点赞 2018-06-13 22:27:31
    一、并行计算  简单地说,并行计算就是在并行计算机上所做的计算。从普通意义上讲,它和常说的高性能计算、超级计算等是同义词。并行计算的初衷是为了努力仿真自然世界中一个序列中含有众多同时发生的、复杂且相关...
  • 并行计算相关书籍

    2018-09-12 23:35:03
    包括《并行计算——结构.算法.编程》、《高性能计算之并行编程技术-MPI并行程序设计》、《MPI参考手册》三本书,资源收集不易,多多支持,共同学习。
  • 并行计算习题答案

    2017-10-12 15:59:32
    本资源是《并行计算 - 结构算法编程》一书的课后习题部分解答
  • 一份基于mapreduce的并行算法设计的课件,介绍了算法的原理以及几种实现
  • 粒子群算法并行实现算法,有利于加深对粒子群算法的理解
  • 并行计算复习第二篇 并行计算理论基础:并行算法设计Ch5 并行算法与并行计算模型5.1 并行算法的基础知识1.并行算法的表达(1)par-don个节点并行完成for循环(每个节点不同,和i相关):for i = 1 to n par-do ... ...
  • 并行算法设计与分析+第3版+陈国良编著+2009+源代码
  • 改进的并行积分算法低通滤波器的FPGA设计.
  • 并行程序开发主要在于并行程序的设计、调试、维护和监控。 一、并行程序开发环境 现在研究重点是扩充现有的编译系统的并行语言功能,主要为: 数据级并行(利用Fortran等开发); 任务级并行(利用MPI、Linda等开发...
  • 2020/1/20 Parallel Algorithms Chapter 13 Y .Xu Copyright USTC 1 / Ch13 Numerical Algorithms Parallel Algorithms 主要内容 ? 13.1 稠密线性方程组求解 ? 13.2 稀疏线性方程组的求解 ? 13.3 非线性方程的求根 ...
  • 并行计算模型及其算法设计,并行计算模型及其算法设计

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 130,317
精华内容 52,126
热门标签
关键字:

并行计算算法设计