并行计算有向无环图和fork/join 框架

从多任务OS开始,线程主要用来表示IO异步;而今随着4G和多核等的到来,计算密集型又热门起来了。

硬件价格和性能从低到高:

PC/Laptop multi core, memory shared

PC clusters

SuperComputers

假设一个理想并行计算机:每个处理器计算能力相同,忽略调度,

static thread 是对一个虚拟处理器的软件层面的抽象;

static强调的是线程一直存在,不包含线程的创建和销毁。

dynamic multithreded concurrency platform:

通讯协议,负载平衡调度器

spawn a subroutine

parallel loop

并行计算有向无环图

只有三个关键字: parallel, spawn, sync

并行控制指令:spawn, sync, return(包括函数末尾的隐式return)

不包含并行控制的指令序列表示为一个顶点;

顶点u到v的有向边表示指令序列u必须先于v执行; 这时称u,v是串行的,

否则是并行的。

我们把边(u,v)分为:

continuation: 在同一过程实例中,v是u的直接后继。

spawn: 如果u spawn v。

call:  如果u直接调用了v。

return: u返回到调用它的过程,v是这个过程里面紧接sync的。

性能度量

work 是指仅在一个处理器上总的执行时间。如果把一个顶点的执行时间是1,

则work就是顶点总数。

span 是图中最长的路径执行的时间。如果一个顶点花的时间是1,

则span等于图的关键路径长度+1。

Tp记为用p个处理器所花的的总时间。

P*Tp >= T1

T1 是用1个处理器所需的时间,显然,T1 = work。

Tinf 表示用无穷多个处理所需的时间, 显然,Tinf = span。

T1/Tp 称为加速量(speedup)。如果T1/Tp = P, 则称为perfect linear speedup。

T1/Tinf 称为并行度(parallelism)。

T1/(P*Tinf) 称为slackness。

一个好的调度器追求的目标就是越来越接近perfect linear speedup。

贪心调度器:在每个时间步,把尽可能多的顶点分配给处理器。

定理: 使用贪心调度器, Tp <= T1/P + Tinf。

实践中,

slackness 至少是10,则Tinf < 0.1 T1/P,从而Tp <= 1.1 T1/P,对于工程应用已经足够好了。

这里我们看到并不是并行度越大越好。

例1

FIB(n)

if(n <= 1)return n;

else x = spawn FIB(n-1)

y = FIB(n-2)

sync

return x + y;

T1(n) = T(n) = \phi^n;

Tinf(n) = max(Tinf(n-1), Tinf(n-2)) + 1

= n;

容易看到,n值不用太大,就可以达到perfect linear speedup.

例2

MATVEC(A,x)

n = A.rows;

parallel for i = 1 to n

yi = 0;

parallel for i = 1 to n

for j = 1 to n

yi = yi + aij * xj;

return y;

把第二个parallel 用spawn来实现:

MATVEC_LOOP(A, x, y, n, 1, 8);

MATVEC_LOOP(A, x, y, n, i1, i2)

if i1 == i2

for j = 1 to n

yi = yi + aij * xj;

else mid = (i1+i2)/2;

spawn MATVEC_LOOP(A, x, y, n, i, mid);

MATVEC_LOOP(A, x, y, n, mid+1, i2);

sync

spawn 个数对应为二叉树内部节点个数=叶子树n-1,总共有n个叶子,因此额外开销spawn分摊到每个叶子为常量。 每个叶子的计算量此时不能再看做1,而是n。因此

span = lgn + n,

work = n^2,

并行度 = n.

如果对for j 也加上parallel, 则并行度可达到n/lgn。

工程实践:

C/C++ 有 gcc/cilkplus, 因为我下载网上的x64二进制文件, 一直搞不定LD_LIBRARY_PATH,需要从源码编译工具链, 有空的时候练一下。

java 有fork/join framework ,这个框架有什么优点?

当一个fork子问题join等待另一个子问题时,会去偷尚未运行的子问题来执行。

因此每个子问题应该避免使用synchronized,sleep,阻塞IO或过多访问共享变量。

ForkJoinTask类的抽象方法比较多,不适合直接继承,而是继承它的子类RecursiveTask/Action。

子问题执行由ForkJoinPool来调度。

work stealing 如何做到负载平衡?

每个工作线程A都有自己的一个队列。当A划分出一个新任务,把它加入到队列头部(TBD);只有A才可以操作它的队列头部并取出来执行。

当A的队列为空时,它将尝试从另一线程B的队列尾部偷一个任务。

由于这种队列操作特性,是的最大的任务排在队列尾部,从而是的其他线程来偷取实现负载平衡。

一个简短的例子说明多线程的优势:

参考:

[0] 算法导论第三版

[1] 两种任务分发方式的比较: http://stackoverflow.com/questions/7926864/how-is-the-fork-join-framework-better-than-a-thread-pool

[2] concurrent collections 的介绍: http://www.ibm.com/developerworks/cn/java/j-tiger06164/

[3] parallel for: http://stackoverflow.com/questions/4010185/parallel-for-for-java

并行计算有向无环图和fork/join 框架

时间: 2024-10-09 01:49:26

并行计算有向无环图和fork/join 框架的相关文章

UVA10305 Ordering Tasks(有向无环图排序--toposort) Kahn算法

题目描述:https://vjudge.net/problem/UVA-10305 题目分析: 恨水的题目,只要学了toposort就会做的,大概意思是给你n个变量,m个不等关系表示a<b,问n个数可能的关系;不如举个例子例如n=3表示3个变量我们假如他们是a,b,c现在有两个关系a<b,a<c 那么输出有两种a<b<c或者a<c<b(题目要求输出任意一种); 题目大概就这个意思,那么我们怎么做呢,我们想一想如果把变量看成点,关系看成有向边,那么就得到一个图,这个

图的邻接表表示与无环图的拓扑排序

一.  图的最常用的表示方法是邻接矩阵和邻接表. 1,邻接矩阵 邻接矩阵其实就是一个二维数组,对于每条边<u,v>,我们就令A[u][v] = 1,如果图为有权图,我们也可以令A[u][v]等于该权,这么表示的优点是非常简单,但是它的空间需求很大,如果图是稠密的,邻接矩阵是合适的表示方法,如果图是稀疏的,那这种方法就太浪费空间了,下面给出图的邻接矩阵表示例子. 2 邻接表 邻接表是图的常用储存结构之一.邻接表由表头结点和表结点两部分组成,其中图中每个顶点均对应一个存储在数组中的表头结点.如下图

HDU 3249 Test for job (有向无环图上的最长路,DP)

 解题思路: 求有向无环图上的最长路,简单的动态规划 #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <vector> #include <cmath> #define LL long long using namespace std; const int

48. 蛤蟆的数据结构笔记之四十八的有向无环图的应用关键路径

48. 蛤蟆的数据结构笔记之四十八的有向无环图的应用关键路径 本篇名言:"富贵不淫贫贱乐 ,男儿到此是豪雄.-- 程颢" 这次来看下有向无环图的另一个应用关键路径. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47135061 1.  关键路径 与AOV-网相对应的是AOE-网(Activity On Edge)即边表示活动的网.AOE-网是一个带权的有向无环图,其中,顶点表示事件(Event),弧表示活动,权表

javascript实现有向无环图中任意两点最短路径的dijistra算法

有向无环图 一个无环的有向图称做有向无环图(directed acycline praph).简称DAG 图.DAG 图是一类较有向树更一般的特殊有向图, dijistra算法 摘自 http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijk

有向无环图的最小路径覆盖 二分图模型解题

有向无环图中,路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一次). 最小路径覆盖就是找出最小的路径条数,使之成为原图的一个路径覆盖. 公式:最小路径覆盖=(原图)顶点数-对应的二分图的最大匹配数. 我们通过例题来解释如何把DAG转换为二分图模型. HDU1151Air Raid 题目大意:在一个城镇,有n个路口,和m条单向路,而且这些路不会形成环.现在要弄

PGM学习之六 从有向无环图(DAG)到贝叶斯网络(Bayesian Networks)

本文的目的是记录一些在学习贝叶斯网络(Bayesian Networks)过程中遇到的基本问题.主要包括有向无环图(DAG),I-Maps,分解(Factorization),有向分割(d-Separation),最小I-Maps(Minimal I-Maps)等.主要参考Nir Friedman的相关PPT. 1  概率分布(Probability Distributions) 令X1,...,Xn表示随机变量:令P是X1,...,Xn的联合分布(joint distribution).如果每

有向无环图

1804: 有向无环图 Time Limit: 5 Sec     Memory Limit: 128 Mb     Submitted: 751     Solved: 313 Description Bobo 有一个 n 个点,m 条边的有向无环图(即对于任意点 v,不存在从点 v 开始.点 v 结束的路径). 为了方便,点用 1,2,…,n 编号. 设 count(x,y) 表示点 x 到点 y 不同的路径数量(规定 count(x,x)=0),Bobo 想知道 除以 (109+7) 的余

有向无环图的应用—AOV网 和 拓扑排序

有向无环图:无环的有向图,简称 DAG (Directed Acycline Graph) 图. 一个有向图的生成树是一个有向树,一个非连通有向图的若干强连通分量生成若干有向树,这些有向数形成生成森林. 在工程计划和管理方面的应用 除最简单的情况之外,几乎所有的工程都可分为若干个称作“活动”的子工程,并且这些子工程之间通常受着一定条件的约束,例如:其中某些子工程必须在另一些子工 程完成之后才能开始.对整个工程和系统,人们关心的是两方面的问题: 一是工程能否顺利进行,即工程流程是否“合理”: 二是