上述定义的邻接矩阵是非对称的,因为当a(i,j)=1和a(j,i)=1同时生时就会构成一个环路。
例如,图的邻接矩阵A如下。
矩阵A有一些很有趣的性质值得研究.若在i行每一个元素都等于0,则结点i是一个输入结点;若j列上都等于0,则结点j是一个输出结点.可以用等式表示为:
此外其他结点都是内部结点。
在矩阵A中,第0,1和2行的元素都是0,表示结点0、结点1和结点2都是输人结点,这三行的元素都用黑体显示。
第7列和第9列的元素都是0,表明结点7和结点9都是输出结点,这两列的元素也都用黑体显示。
其他行和列中都有超过1个非零元素,表明这些结点都是内部结点。
若结点i有元素a(i,j)=1则说结点J是结点i的母结点。
依据子任务的依赖关系可以大致将算法分为如下几类:
(1)串行算法。
(2)并行算法。
(3)串行一并行算法(SPA).
(4)非串行一并行算法(NSPA)
(5)正则迭代算法(RIA)
最后一类算法可以看做SPA的泛化。
值得一提的是,根据数据或者任务的粒度的不同,算法的分类也随之改变。
例如说,如果矩阵的元素相加是一项基本操作,求两个矩阵的和就可以看做是一个串行算法。
若另一台计算机上的基本操作是相关行列的相加,那我们的算法就变成了基于行列的并行算法。
另一项值得一提的事情是,一些算法的子任务可能会有不同类型的算法。
依旧可以用矩阵相加的运算来说明。
在并行计算机中两组相关行的计算可以同时在两个不同的处理器上执行。
但在每个处理器上相关行上的元素又是串行处理的,因此这个并行算法中就包含了行相加的串行算法。
稍后我们会详细讨论这些分类。
串行算法的特点是由于相互之间存在数据依赖关系,子任务必须一个一个地按顺序执行。
这一类算法的DG是由一系列关联的子任务构成的队列图1.3(a)展示了一个串行算法的DG。
此类算法是用来计算斐波那契数列的。
为了得到n10,子任务T10进行了如下计算:
n10=n8+n9
在此n0=1和n1=1初始条件已经给出.很明显,为了得到某一位的斐波那契数只能依次计算在它之前的数。
并行算法的特点是由于相互之间不存在数据依赖关系,子任务可以同时并发执行。
此类算法的DG就像是许多独立的子任务组成的一组任务,相互之间没有联系。
图1.3(b)展示了一个并行算法的DG,Web服务器上的数据处理应用就是一种简单的并行算法,每一次数据请求都被看做独立的任务交给不同的处理器来响应.同时运行浏览器,字处理程序等多个程序时操作系统的多任务调度算法也是一种并行算法。
SPA
SPA的特点是子任务被分配推不同层次,每个层次之内的子任务可以并发执行,但是各个层次需按照一定的顺序执行.当需要执行的层次只有一层时,这个SPA就是并行算法。
当每一层都只有一个子任务时.这个SPA是串行算法。
图1.3(c)展示了CORDIC算的DG,CORDIC算法就是一个典型的SPA它有n层迭代,在第i次迭代时需要执行以下运算:
在此等式中x,y和z都是进行迭代的数据.每次迭代之后都会被更新。
和
是存在表单中的常量.m是用来控制计算类型的参数,
的数值是预设的.与i有关.此算法每次迭代都会进行这三项操作,这里并不研究该算法的细节。
NSPA
NSPA不属于上述分类中的任何一种,NSPA算法的DG也没有规律可循。
根据算法DG是否有环我们将NSPA分为两大类:
(1)DAG。
(2)有向有环图(DCG),
图(a)展示了一个DAG算法,图(b)是一个DCG算法.DCG算法常见于离散时间回谈控制系统。
输入信号作为子任务T0的初始滤波或者愉人信号条件.子任务T1的输出通常是错误信号,然后这个信号会作为一种反馈输入子任务T2中。
NSPA的依赖图有两种典型构造:
结点用来表示构成算法的子任务,有向边则表示子任务之间的数据流向.一个结点的一条出线表示输出,入线表示的是输入。
若Ti的输出指向Tj,我们则说Tj依赖于Ti.在图中我们则用“结点i的一条有向边指向结点j”来表示这种依赖关系。
一个算法的DG有如下3个重要属性:
(1)Work任务数(W)表示算法完成需要处理的子任务总数。
(2)Depth深度(d)表示任f“个输人结点到任意一个输出结点之间的最大路径长度,也被称为关键路径。
(3)Parallelism并行度(P),也被称为并行程度,表示可以并发执行的最结点数.由此数据可以决定这个算法需要的处理器的数目不会超过P,这样一来在算法执行过程中就不会出现不必要的空闲处理器.
第8章会对这些性质进行进一步探讨上实现。
此外还会研究如何将这样的算法在并行。
RIA
Karp等介绍了RIA的概念.此类算法需要特别加以说明,因为此类算法涵盖范围甚广,包括信号处理、图像和视频处理,线性代数应用。
以及基于网格结构的数字模拟程序,图是一个RIA的依赖图,用作示例的是图像匹配算法。
对干RIA算法我们不绘制DAG来表示.而是用依赖图的概念来表示.
依赖图和DAG类似.但是依赖图中的连接边是无向边.依赖图的具体画法在第9章,第10章以及第11章会详细叙述.
RIA中的任务依赖关系图十分复杂。
串行算法和并行算法,甚至SPA算法的并行度计算都不复杂。
但是RIA算法的并行度计算十分困难。
矩阵乘算法就是简单的RIA算法,具体见算法
算法中出现的变量和算法的因子i,j,k有着正则依赖关系。
一般情况下此类算法通过依赖图来进行研究,依赖图能展示需要执行的子任务之间的关系。
当算法只有1个或2个因子时,依赖图是很直观的。
但是矩阵相乘算法出现了3个因子,因此它的依赖图是三维的,很难直观表示。
并行算法实现
上一节讨论了根据子任务之间的依赖关系不同,我们将算法分为几个不同的类别,本节将探讨根据算法的类型如何将算法在并行计算机上利用软件或硬件实现。
这涉及算法的并行化.根据算法的类型不同采取相应并行化的策略。
设计并行计算系统
本节讨论的是在设计并行计算系统时需要注意的一些重要问题.并行计算系统的设计需要考虑许多方面。
设计者需要选择一个能处理预期任务的基础处理器架构。
处理器应该是一个简单的单元,也可以是一个能运行多线程操作系统的超标量处理器。
处理器之间的通信应采用内部互联网络.此网络应该有能力支持任意两个处理器之间的即时通信。
处理器之间的连接方式类似于电信中的信道。
数据交换的方式需要详细的说明。
总线互联是最简单的内部互联网的实现方式.数据的交换基本单位是字。
系统有一个时钟负责通知处理器数据是否可用。
如今总线已经被网络芯片(NoC)代替.数据在网络芯片上交换的基本单位是数据包,使用路由器来计算数据之间的传输线路.
数据和程序需要储存在特定的内存系统中,设计者可以选择让处理器共享内存模块.或者可以为每一个处理器都分配特定的内存模块。
若采用共享内存的设计,系统需为读和写操作分配不同的内存模块。
读和写的顺序需保证数据完整性.若某个数据被某个处理器更改过,其他处理器应被告知此更改以确保数据的正确性.
任务或者程序在一个并行计算机上的实现需要考虑如下问题.任务分割表示将原始程序或应用分为几个程序段,以便稍后将它们分配至各个处理器上.粗粒度分割是指分配至各个处理器的程序段体积较大.细粒度分割则是指程序段的体积较小。
程序段可以是不同的软件进程或者是线程.由程序员或者编译器决定分割方式.程序员或者操作系统必须要确保子任务的同步执行以保证程序的正确性和数据的完整性.
并行算法和并行体系结构
并行算法和并行体系结构是紧密结合在一起的。
在思考并行算法的时候必须要考虑到支撑这个算法的并行硬件系统。
同时,在设计一个并行硬件系统的时候也不能不考虑在其上运行的并行算法.并行计算在一个计算机系统上的实现的层次是不同的,可以通过硬件实现、也可以由软件来实现。
数据级并行是指同时对数据的多个位或者多个数据进行运算,例如位并行加法和二进制除法,向量处理器阵列以及处理多份数据样本的脉动阵列都属于数据级并行。
数据级并行是本书的主题。
(1)指令级并行(ILP)是指处理器同时执行多条指令,例如指令流水线的应用。
(2)线程级并行(TLP)。
线程是程序的一部分,线程之间共享处理器资源。
有些时候线程也被称为轻量级进程。
TLP是指由一个或者多个处理器同时执行某个软件的多个线程.
(3)进程级并行。
进程就是指计算机正在执行的程序。
一个进程会占有特定的计算机资源,例如专用的内存空间和寄存器。
通常意义的进程级并行就是指多任务处理或者分时计算系统,即在一台或者多台计算机上同时运行几个程序。
并行算法和并行体系结构相关概念
IEEE电子工程名词标准词典里将软件的“并行”定义为:
“分别使用独立的设备,并且在同一时刻转移、产生或者处理构成一个整体的几个独立部分,例如构成一个字符的每一位,或者构成一个字的每一个字符。
”在此定义之下,若一个算法的某些步骤可以分别由不同的硬件同时处理,我们就可以说此算法是并行的。
定义并行算法的时候已经默认了存在支持并行算法运行的硬件环境,这同时表明软件的并行化与执行这个软件代码的硬件是密不可分的。
软件的并行通过使用不同的线程或者进程来实现,而并行基于硬件的实现则是通过使用不同的处理器。
当代码中出现FOR或者WHILE这类的关键词的时候,能很快得出此算法可以并行的结论。
IEEE电子工程名词标准词典里对于“并行体系结构”的定义如下:
”可以执行并行处理的多处理器结构”。
为多个处理器分配任务以保证系统高效率工作是程序员和编译器以及操作系统的职责。
在如下领域中我们可以找到许多并行算法的实例:
·科学计算领域中的物理仿真,微积分公式求解,风洞测试模拟。
·计算机图形学领域中的图像处理,视频压缩,以及光线跟踪。
·医学成像领域中的核磁共振成像(MRI)以及计算机断层x线扫描术(CT).
在很多领域,特别是在信息技术领域中,包括在线医疗数据检索、网上银行业务、数据挖掘、数据仓库以及数据库检索系统中并行算法并没有得到充分应用。
通过开发来提升IT应用的计算机体系结构和软件是当前面临的诸多挑战之一。
算法的实现:
两个方面问题
图展示了本书将探讨的一些问题,左侧表示算法空间,右侧表示执行算法的并行体系结构空间.路径A表示的情况如下:
已知一个具体算法,要满足预期的性能并考虑系统的限制,需要为实现此算法寻求合理的硬件结构或者处理器阵列。
此时的问题简而言之就是为给定的并行算法寻求可行的并行硬件体系结构。
路径B表示如下一种常见的情况:
并行体系结构或者多核系统是已知的,要解决的问题是在满足预期的性能并考虑系统限制的条件下,为并行算法的实现寻求最优解。
简而言之就是在一个给定的体系结构中研究如何将并行算法的任务合理地分配至处理器端。
这需要程序员、编译器与操作系统一起来解决此问题,它涉及多线程并行编程技术。
不论是选择路径A还是B都需要解决以下问题:
(1)将子任务映射至不同的处理器。
(2)遵循算法的数据依赖关系和数据的I/O要求,合理调度子任务的执行顺序。
(3)识别I/O接口和处理器之间的数据交换。
衡量并行计算的优势
本节回顾一下之前的一些重要结论,列举使用并行计算带来的好处。
但首先要讨论一些用于定量分析的重要指标。
衡量一个并行计算是否优秀的一个重要标准是对比某个任务在单处理器和N个并行多处理器上的执行时间。
N个并行处理器的加速比S(N)可以定义为:
其中Tp
(1)表示单处理器系统运行算法的时间,Tp(N)表示多处理器系统运行算法的时间.理想条件下,忽略处理器和内存之前的通信时间,在一个完全并行化的算法中Tp(N)=Tp
(1)/N,则上述等式变为:
但在现实情况中很难得到这样的结果,原因会在以后的章节中说明.
无论是并行系统还是单处理器系统,计算数据的读取和写人都是不可避免的步骤.内存的通信开梢是由于处理器和内存之间的信息交换速度的不对称。
此外,在并行系统中
处理卷之间也有大显数据交换,例如在内部网络中的信息交换和数据的转移.”
处理器之间的通信主要有如下几点困难需要克服:
(1)内部网络延迟:
通过内部互联网络发送数据会产生位传播延迟,数据发送延迟,以及内部队列等待延迟。
影响内部网络延迟的因素有网络拓扑结构,数据的大小,以及网络响应速度等。
(2)内存带宽限制:
无论内存有多大,内存的数据交换和访问只能通过某一个单独的接口.而且一次只能处理一个字的读或者写操作。
(3)内存冲突:
当两个以上的处理器同时访问同一个内存模块时会造成内存冲突。
需要一个仲裁机制来决定在此种情况下由哪一个处理器优先获取访问权限。
(4)内存墙:
由于内存的读写速度远小于处理器的速度,内存墙便诞生了。
解决此问题的方法是使用多级内存,例如如下结构:
寄存器-高速缓存器-RAM-电子磁盘-磁盘-光盘
在并行处理器系统上运行一个并行算法时我们将会遇见多种延迟,详见表1.1.
假设某并行算法有N个独立的子任务,每个子任务都同时可以被一个或N个处理器执行,在此种理想条件下,由于每个子任务都是相对独立的,数据只需在处理器和内存之间交换.而不会出现处理器之间的数据交换.理想条件下可以得出如下等式:
单个处理器读取算法愉人数据所需时间为:
此等式中
表示内存访问某个数据块所需要的时间。
假设上述等式中的每个子任务都需要输人一个数据块,N个子任务需要输人N个数据块,则并行处理器从内存中读取数据的时间可以表示为:
表示共享内存受限访问因子。
当每个处理器都拥有一份自己需要的数侧备份时,
=1/N.当由主存模块以此为每个子任务分配数据时
=1.在最坏的情况下
>N,此时每个处理器都需要从共享内存中读取数据,从而产生了内存冲突.可以把上述内容总结为:
若处理器试图访问同一组内存模块时,将结果写回内存也有可能发生冲突
对单一处理器而言,完成一个任务所需的时间(包括内存通信时间开销)表示如下:
考虑到通信开销的加速比计算等式如下:
内存不匹配比(R)的定义如下:
R表示从内存读取一个数据块的延迟和处理一个数据块的延迟的比位.根据子任务的粒以及内存读写的速度不同,
应比
小几个数量级。
还可以将等式(1.17)用N和R表示为:
图展示了以N和R为参考量,在
=1的情况下加速比的变化情况。
数学模拟结果显示
的变化对结果并无显着影响。
由以上等式可知,在RN<<1的情况下可以得到最大的加速比,此结果与等式(1.7)中忽略通信开销的结论相符合。
此种情况发生时我们就称此算法是一个平凡并行算法,将在第7章详细讨论.
注意在RN>O.1时加速比开始迅速下降.当R=1时出现了通信边界问题,井行化的优势也消失了。
这提醒我们内存系统的设计和处理器之间的通信问题是很重要的。
第3章还会讨论多核处理器.由于多核处理器将处理单元都染成在一块芯片上,相比于跨芯片的多处理器系统,多核处理器的处理单元之间的通信速率拐到了大辐提升。
在多核系统中Tm减小了几个数量级,R值也大幅减小。
考虑内存的读写时间,多核处理器间的通信开销表示如下:
其中
》=0,由内存系统和算法决定.
=0时表示单处理器系统,处理器之间无数据交换。
在某些算法中p的值可能等于log2N甚至等于N,其原因可能是程序员在编程时完全没有考虑到处理器之间的通信问题。
针对多处理器系统的Amdahl法则
假设一个算法或者一个任务