并行计算同步计算
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
barrier( barrier( mygroup ); //用路障使各进程同步 //用路障使各进程同步
例 2:对数列A = (x0 , x1 ,…, xn-1)求其前缀和数列 对数列A x0 , x0 + x1 , … , x0 + x1 +…+ xn-1 项为: 即前缀和数列中的第 i 项为: x0 + x1 +…+ xi 顺序代码: 顺序代码: for ( i = 0; i < n; i++) { sum[ i ] = 0; for ( j = 0; j <= i; j++) sum [ i ] = sum[ i ] + x [ j ]; } 其时间复杂性为O( 其时间复杂性为O( n2 )。
3、树实现 :利用树结构实现的同步方法
假设有 8 个进程 P0~ P7,路障同步完成的过程为: 第一级:
当 P1 到达路障时, P1 给 P0 发送消息; 当 P3 到达路障时, P3 给 P2 发送消息; 当 P5 到达路障时, P5 给 P4 发送消息; 当 P7 到达路障时, P7 给 P6 发送消息;
第二级:
当 P2 到达路障且P2已收到P3发来的消息时,P2 给 P0 发送消息; 到达路障且P 已收到P 发来的消息时,P 当 P6 到达路障且P6已收到P7发来的消息时,P6 给 P4 发送消息; 到达路障且P 已收到P 发来的消息时,P
第三级:
当 P4 到达路障且P4已收到P6发来的消息时,P4 给 P0 发送消息。 到达路障且P 已收到P 发来的消息时,P
进程不在同一时刻到达障碍点的情况
进程
P0 活 动 P1 P2 Pn -1
…
时 间
等 待
障碍
…
在消息传递系统中,障碍同步通常是由库例程(函 数)提供的。 MPI 的障碍同步例程: barrier(comm) 阻塞所有的调用者,直到通信体 (comm)中所有 (comm)中所有 的成员都调用了该例程后, 的成员都调用了该例程后,各进程中的 barrier 调用才可返回。 PVM 库也有类似的例程: pvm_barrier( ) 障碍同步例程的实现取决于并行系统的体系结构。
例1’ :两个具有n个元素的数组进行相加数据并行 两个具有n 代码可写为: 代码可写为: forall ( i = 0; i < n; i++ ) A[ i ] = B[ i ] + C[ i ]; 如果希望将数组 A 的第 i 个元素加上 i,其数据并 行代码可写为: 行代码可写为: forall ( i = 0; i < n; i++ ) A[ i ] = A[ i ] + i ; 数据并行技术可以应用到多处理机和多计算机系统 上
常用的解决办法: 常用的解决办法:两进程的发送和接收例程 的顺序做调整。 的顺序做调整。 Pi
recv(Pj); send(Pj);
Pj
send(Pi); recv(Pi);
对流水线系统而言, 对流水线系统而言,我们可以利用下列办法 避免死锁的发生: 避免死锁的发生:
对编号为奇数的进程先接收消息再发送消息; 对编号为奇数的进程先接收消息再发送消息;而 对编号为偶数的进程首先发送消息然后再接收消 息。
Pk
recv(Pj); send(Pj);
死锁
正如操作系统中的同步一样,并行系统中同步也会 出现死锁问题; 如果要通过接收/ 如果要通过接收/发送消息实现两进程彼此的同步:
Pi
send(Pj); recv(Pj);
Pj
send(Pi); recv(Pi);
可以看到:若两进程的send例程是同步或阻塞的, 可以看到:若两进程的send例程是同步或阻塞的,则 send例程是同步或阻塞的 两进程均会等待对方匹配的接收例程而造成死锁。 两进程均会等待对方匹配的接收例程而造成死锁。
1、障碍(路障)同步(barrier synchronization): 障碍(路障)同步(barrier synchronization): 在并行系统中,使一组进程取得同步的一种方法。 在并行系统中,使一组进程取得同步的一种方法。 它在参与障碍同步的每个进程的程序中彼此必须 等待的位置设置一个障碍点, 等待的位置设置一个障碍点,当某进程执行到障 碍点时暂停, 碍点时暂停,等待所有进程都执行到这个障碍点 它们才能继续运行。 上,它们才能继续运行。 通常需要同步的进程的程序中有多个障碍点,以同 通常需要同步的进程的程序中有多个障碍点, 步它们彼此的操作。 步它们彼此的操作。 障碍同步可应用于: 障碍同步可应用于: 共享存储器系统 分布存储的消息传递系统
更有效的顺序代码: 更有效的顺序代码: for ( i = 1; i < n; i++) x [ i ] = x [ i ] + x [ i -1]; 该顺序算法的时间复杂性为O( )。 该顺序算法的时间复杂性为O( n )。 该代码段可并行性很差。 该代码段可并行性很差。
1986年由 1986年由 Hillis 和 Steel, Jr.提出的另一种求前缀和 Jr.提出的另一种求前缀和 的方法,它具有良好的可并行性。 的方法,它具有良好的可并行性。 其顺序代码:假设 n 是 2 的整幂次 其顺序代码: for (j = 0; j < log(n); j++) /* at each step, add*/ for (i = 2 ; i < n; i++) /* to accumulating sum*/ x [ i ] = x [ i ] + x [ i – 2 ]; 正确的顺序代码: 正确的顺序代码:假设 n 是 2 的整幂次 for (j = 0; j < log(n); j++) for (i = n-1; i >= 2 ; i - -) (i nx [ i ] = x [ i ] + x [ i – 2 ];
局部同步
全同步要求所有的进程同步,但实际问题中常有些 局部同步的情况。 对于局部同步的情况,我们只需在要求同步的进程 之间实现即可。 例如:在进程 Pi、Pj 和 Pk 之间实现同步是利用彼此 间的接收/ 间的接收/发送空消息完成的:
Pi
recv(Pj); send(Pj);
Pj
send(Pi); send(Pk); recv(Pi); recv(Pk);
同步计算是指那些带有全同步或大量部分同步 的计算。
主要内容
一. 全同步及相关技术问题 二. 同步计算 三. 同步迭代程序实例
一、全同步及相关技术问题 一、全同步及相关技术问题
在消息传递并行计算中,常用的全同 步的实现方法有:
1. 2. 3.
障碍、路障(barrier) 障碍、路障(barrier) 计数器实现 树实现
……
计数器路障分为两个阶段:
进入路ቤተ መጻሕፍቲ ባይዱ阶段 离开路障阶段
如果系统没有路障例程,通常由主进程维护 路障计数器:
当从进程到达路障时,主进程对来自从进程的消 息计数; 在离开路障阶段中,主进程释放各个从进程。
以上路障方法的主进程代码:
/*count slaves as they reach barrier*/
树型路障实现过程
P0 到 达 路 障 P1 P2 P3 P4 P5 P6 P7
离 开 路 障
树型障碍同步算法(SPMD) 假设n 树型障碍同步算法(SPMD):假设n是2的整幂次 (SPMD):
/* 到达阶段 */ for (i = 0; i < log(n); i++) if (myid % 2i == 0) if (myid % 2i+1 == 0) recv(Pmyid+2i); else send(Pmyid-2i); myid/* 离开阶段 */ ifor (i = log(n) -1; i >= 0; i- -) if (myid % 2i == 0) if (myid % 2i+1 == 0) send(Pmyid+2i); else recv(Pmyid-2i); myid-
第六章 同步计算
Synchronous Computations
同步计算分为全同步和部分同步
全同步 (full synchronination):所有的进程在一 synchronination):所有的进程在一 些规则的执行点上的同步。 部分同步(partial synchronization)或局部同步 部分同步(partial synchronization)或局部同步 (local synchronization) :在逻辑上相邻的一组 进程参与的同步。
另外,对进程间双向数据传输可能造成的死锁问题, 另外,对进程间双向数据传输可能造成的死锁问题, 及其它一些并行例程库中, MPI 及其它一些并行例程库中,提供了一个复合阻塞 例程sendrecv( ); 例程sendrecv( );这个例程通过系统内部实现机制来 避免死锁的发生。 避免死锁的发生。
对应的从进程代码:
send(Pmaster); recv(Pmaster);
for (i = 0; i < n; i++) recv(Pany);
/* release slaves */
for (i = 0; i < n; i++) send(P i );
从主进程代码可以看出:计数器路障的实现的时 间复杂性为:О(n)。 间复杂性为:О(n)。
Pi
recv(Pj); send(Pj);
Pj
send(Pi); send(Pk); recv(Pi); recv(Pk);
Pk
recv(Pj); send(Pj);
上述情况可改写为: 上述情况可改写为:
Pi
sendrecv(Pj);
Pj
sendrecv(Pi); sendrecv(Pk);
Pk
sendrecv(Pj);
同步计算的一个典型应用例子是同步迭代 同步计算的一个典型应用例子是同步迭代
数据并行计算
例1:两个具有n个元素的数组进行相加: 两个具有n个元素的数组进行相加: A[ ] = B[ ] + C[ ]; 相应的串行代码可写为: 相应的串行代码可写为: for ( i = 0; i < n; i++ ) A[ i ] = B[ i ] + C[ i ]; 我们可以看出语句 A[ i ] = B[ i ] + C[ i ]; 可以同时 放在不同的处理机上执行, 放在不同的处理机上执行,当处理机的个数为 n 时, 个处理机只需计算: 第 i 个处理机只需计算: A[ i ] = B[ i ] + C[ i ]
二、同步计算
全同步计算典型的例子是数据并行计算 全同步计算典型的例子是数据并行计算
数据并行 (SIMD) 计算----所有的进程同时对不同 计算-------所有的进程同时对不同 的数据执行相同的操作。 的数据执行相同的操作。 数据并行计算的优势: 数据并行计算的优势: 容易编程; 容易编程; 可以容易地扩展问题的规模; 可以容易地扩展问题的规模; 可以数据并行方式解决许多数值问题和一些非 数值问题。 数值问题。
数据并行---数据并行----数组相加 ----数组相加
语句 A[ ] = B[ ] + C[ ];
P0
A[0] = B[0] + C[0];
P1
A[1] = B[1] + C[1];
…
Pn - 1
A[nB[nC[nA[n-1] = B[n-1] + C[n-1];
并行程序设计语言中有一个专门用于说明数据并行 的语句结构: 语句。 的语句结构: forall 语句。 语法: 语法:forall ( i = 0; i < n; i++ ) { body } 语义: 语义:body 中的语句序列的 n 个实例被同时执 行。 循环变量” 的每一个值仅对一个实例有效, “循环变量” i 的每一个值仅对一个实例有效, 即: 的第一个实例有效; i = 0 时,对 body 的第一个实例有效; 的第二个实例有效; i = 1 时,对 body 的第二个实例有效; ……
进程
P0 P1 Pp- 1
: : : barrier( ); : : :
: : barrier( ); : : : :
……
: : : : barrier( ); : :
各进程处于等待状态, 各进程处于等待状态, 直到所有的进程都到达 barrier调用点为止 调用点为止。 barrier调用点为止。
实际上数据并行计算不适合应用在基于消息传递的 并行系统中, 并行系统中,这是因为每一步操作都需要显式地调 用障碍同步例程。 用障碍同步例程。
如前面的例子,其 SPMD 的代码为: 的代码为: 如前面的例子, i = myrank; A[ i ] = A[ i ] + i; // 得到自己进程编号 // 做 body 的一个实例
2、集中式计数器实现 :用一个计数器对到达路障的 进程数目计数。
计数器的初值为 0; 每个调用路障的进程将计数器增 1,并检查计数器是否已 到达路障同步进程总数 n;若未到达 n 值,则使进程转入 “挂起” 状态;否则释放该进程及所有其它等待进程。 计数器 : : : barrier( ); : : : : : barrier( ); : : : : : : : : barrier( ); : :