MIT高级算法之并行计算

来源:互联网 发布:homer软件收费吗 编辑:程序博客网 时间:2024/06/16 15:41

MIT高级算法

2017/9/29

 

 by

CHENJING DING

 


CHAPTER1 – 并行计算 Parallel algorithms


注:本篇文章是MIT高级算法课程中的并行计算课程的笔记,其中红色下划线部分为本人拓展部分,如有错误,欢迎指正。对算法和公式部分的推导也做了尽可能详细的展示,希望能一起交流啦~


我们有很多并行算法的模型(models),对于串行算法(serialalgorithms)而言,一般只有一种基础模型:随机存取机器模型(randomaccess machine model)。下文介绍的是动态多线程(Dynamicmultithreading),适合用于多核机器(multicore machines)。它是为内存共享(sharedmemory)的编程而设计的,不适用于分布式内存编程(distributedmemory programs)。因为每个处理器都有访问内存的权限。



学习调度(scheduling)前的基础知识

计算第n个斐波拉契数的模型(不用弄清楚如何计算)。伪程序(pseudocode)代码如图所示:


衍生Spwan:子程序(subroutine)可以和父程序一起执行。比如程序执行到Fib(n-1),会产生子程序的同时也会执行下一句Fib(n-2)。

同步Sync等待所有子程序完成。必须等到所有x和y都计算出来,才能计算x-y。

下面需要用调度器(schedule)决定如何把这个动态不断衍生的程序映射到可用的处理器上。

 

并行指令流

并行指令流(parallelinstruction)是一个有向非循环图(DAG: directed acyclic graph)。

在这个图中,顶点(vertices)代表线程(threads)。

线程:最长的指令序列(maximal sequences ofinstructions),该序列不包含任何并行控制(spawn,sync,以及从一个衍生的子程序返回)

则上述程序可化为三个顶点,即三个线程。

A:从程序开始到求Fib(n-1)为止,也就是恰好在做子任务跳转前一步

B:在跳转到Fib(n-2)前一步

C:计算x-y

在当前最长的串行指令序列执行时,到执行并行指令时(spawn,sync,以及从一个衍生的子程序返回)就会结束当前的线程,所以我们可以把上述问题看成是三个线程组合。

下面假设我们计算Fib(4),水平的椭圆对应的是程序的执行。其中Fib注释的为当前A线程计算的FIB()值








我们有三条边,分别是继续边,衍生边和返回边。

性能测算(Performance measures)

Tp = 在P个处理器上的运行时间(runningtime)。不是一个常熟,因为不同的调度规则会得到不同的Tp。

T1 = 一个处理器上运行的时间,即为串行运行时间(theserial time)。一个线程在一个处理器上运行的时间称为功。当去掉上述并行指令流(spawn,sync,以及从一个衍生的子程序返回,即衍生边和继续边不能一起同时执行),则上述DAG中有多少节点,就为执行了多少个线程。

T_∞= 关键路径长度(thecritical pathlength),DAG中最长的路径。即处理器有无数多个,运行程序所用的时间。

假设线程的运行时间是一个单位时间,则上述例子中,T1= 17。 T_∞ = 8(如下图灰色节点部分所示,因为这些节点没有办法同时运行,只有运行完父程序的A线程才能执行A线程的衍生程序)。


Tp的下界

T_p>=T1/P。因为P个处理器在一个线程的单位时间内最多做P功(就是每个处理器分别运行一个线程,一共可以运行P个线程)。所以,当功的总量为T1.一共至少要T1/p个线程运行时间。

Tp≥T_∞ . 在一段时间内用P个处理器运行完的程序,当然也可以用无数个处理器运行完。并且P个处理器做的功不可能比无数个处理器做的功还要多

加速比

T1/Tp = 为P个处理器的加速比(speedup),表示P个处理器比单处理器要快多少。

如果T1/Tp=O(p),称为线性加速。   lim【(T1/Tp)/P】=0,可以理解为T1/Tp在关于P的数量级上小于或等于P,所以T1/Tp关于P的数量级为10,即T1/Tp<p

T1/Tp > P 为超级线性加速,是不能发生的。因为Tp的下界为T1>P。

最大加速比和并行度

最大加速比为T1 / T_∞(因为 Tp≥T_∞)。将其称为并行度(parallelism)。

所以并行度 = 功/关键路径的长度。就是在关键路径长度上可以并行完成的功的平均分量。用 P ̅表示。注意 P ̅与P没有任何关系, P ̅是计算量,P是处理器数目。



调度(scheduling)

调度的目的:由编程语言的运行时系统(aruntime system)完成的,将计算分配到P个处理器。

离线调度算法(theoff-line schedulers):

贪心调度(Greedyscheduler)

思想

每一次调度要尽可能使所有处理器都运行程序。分别对应两种情况:

最大完整步骤(complete steps):至少有P个线程准备执行,如果没有处理器(总个数为P个)闲置,则称为此次执行为最大完整步骤。则执行任意P个线程Tp >=T1/P 。因为每一步完整步骤都做了P的功。

不完整步骤(incomplete steps):有少于P个线程准备执行,则执行所有线程。

定理:

一个贪婪调度算法执行任意计算DAG G,若功为T1,关键路径长为T_∞ ,那么它的运行时间Tp=< T1/P + T_∞(在p个处理器上运行)。实际上Tp<2倍以内最优调度时间(因为T1/P,T_∞都是调度时间的下届,都是最优调度时间,取其中最大值)

下面来证明:

令G’为G其中一个要被执行的子图,令P= 3;  G’为还没有执行的线程顶点以及边组成的图(下图中黄色和黑色顶点)。灰色节点表示已经执行完的顶点。再次假设每个线程的运行时间是单位化的。在图G‘中,当一个顶点的入度为0时,则为将要执行的节点。橘黄色节点为下一次即将要执行的节点,因为只有两个,小于P,则下一次执行的是不完整步骤。


图 G

每一次执行完不完整的步骤,G‘要执行的关键路径要减去1。下图中即将执行的是完整步骤(黄色顶点个数大于P),G‘要执行的关键路径不变,除非4个节点都执行完,G‘要执行的关键路径才减去1。

所以,不完整步骤的个数小于T_∞ 。

综上,p个处理器做T1功所需的步骤数目Tp<= 最大完整步骤T1/P+最大不完整的步骤 T_∞。

推论:

如果运行的处理器个数是以并行度 为阶(即小于或等于 )的话,则可以得到线性的加速比,所以如果你的处理器数量是等于或少于并行度的话,贪婪调度算法能给你带来线性的加速。

(2)式表明如果处理器数量小于或等于并行度,则由(6)式可得用贪婪调度可得线性的加速。如果处理器的数量大于并行度,则浪费了,因为不可能存在超线性加速的情况。

所以,并行度可以理解为用贪婪调度实现线性加速的处理器数量的极限。



 

原创粉丝点击