并行与分布式计算导论(四)问题的结构与分解


新的一轮MPI作业已经发布,我尽量在DDL之前给同学们把MPI部分也更新出来!鱼生苦短,争取更咸!

Section 4 问题的结构与分解

OpenMP是我们在C++上进行并行计算的主要库之一。OpenMP是基于内存共享的,适合单机多核、共享内存的系统。所以这里我们关注的是如何将任务做清晰的划分,并交付给一台电脑上的多个处理器进行处理。OpenMP的具体内容将在下一篇文章中讲到,这里首先给出一些OpenMP编程中常常遇到的概念、主要考虑的问题和一些辅助思考的工具。

尽管Foster的设计原则倡导我们要进行四个设计步骤,但实际上OpenMP编程中往往先考虑的是问题的分解和分配问题。分解就是决定哪一部分和哪一部分应该分开,哪一部分先执行哪一部分后执行,哪一部分可以并行,哪一部分只能交给单线程执行;分配就是决定可以并行的任务部分如何分配给不同的处理器,如何权衡并行程度与通讯开销。

问题的分解

同一项工作可以被分解成很多种子任务的组合,不同的分解可能产生多种多样的计算方式和安排方式

并行度(degree of concurrency)

定义:可并行的任务数目

  • 在程序执行中可能发生变化

指标:

  • 最大并行度:在程序执行过程中,并行任务数的最大值
  • 平均并行度:同时并行任务(关于时间的)平均数

并行度与任务粒度(granularity)
(回顾:任务粒度是描述任务划分精细程度的一个指标)

  • 两者处于敌对关系,如果任务分的极为细致,那么并行度很高,任务的粒度就很低,如果任务分的笼统,那么粒度很大,并行度却很低
  • 既要有一定的并行度,以提高效率,也要保证一定的任务粒度,减少代码工作、增强直观可读性

任务依赖关系图

在这里插入图片描述
任务依赖关系图(一个有向连通无环图)反映的是任务间的拓扑关系(前后置关系)。一个任务只有等待指向它的所有前置任务都完成才能开始执行

关键路径(重要)

任务依赖关系图中的边展示了任务的拓扑关系

  • 关键路径:最长权重的路径
    • 关键路径长度决定了并行程序执行时间的下界

任务交互图(Task Interaction Graph)

在这里插入图片描述
注意与任务依赖关系图(Task Dependency Graph)区分,任务交互图展现的是任务间的数据交互关系

  • node=task
  • edge=interaction or data exchange

并行效果

限制并行效果的因素

  • 最小任务粒度(与并行度、任务交互都有关系)
  • 任务间的依赖关系
  • 并行开支(比如任务间通讯的开销)
  • 工作中不能并行化的比例

衡量并行效果的指标

  • S p e e d u p = T 1 / T p Speedup=T_1/T_p Speedup=T1/Tp(单线程时间/p线程时间)
  • P a r a l l e l E f f i c i e n c y = T 1 / ( p T p ) ParallelEfficiency=T_1/(pT_p) ParallelEfficiency=T1/(pTp)

工作的分配

任务、线程与映射

任务(task)

  • tasks是问题中独立的单元
    • 线程将被分配去执行每个task的工作
    • tasks有可能被暂缓
    • tasks可能立刻被执行
  • The runtime system将决定上述内容

注:task、work之类的东西在中文中的意思其实比较类似,在编程实践中也没有严格的区分用哪个名词,以后提到的“任务”到底是指任务单元的task还是工作总体的work读者应该视语境而定

线程与映射

实际操作中将任务分配给threads,而不是cores,threads到cores的映射由OS完成

  • 将tasks分配给threads的映射对于并行程序的效果来说是至关重要的

借助什么工具选择映射

  • 试图将独立的任务分配给不同线程时:使用任务依赖图
    • 最少的线程闲置
    • 最优的负载均衡
  • 试图让线程间交互最少时:使用任务交互图
    • 最少的通讯消耗

一个最好的映射一定要最小化并行执行时间

  • 将不相互依赖的任务映射给不同线程
  • 将关键路径上的任务尽快映射给线程
  • 最小化线程间的通讯
    • 实际上这些原则一般会彼此冲突,例如不分割任务使得交互最少,但完全没有加快速度

猜你喜欢

转载自blog.csdn.net/Kaiser_syndrom/article/details/105225986