您的位置:首页 > 其它

forkjoin并发框架—需求背景和设计原理

2016-05-14 12:50 651 查看

1. Fork Join 的设计简介

看过《Introduction to Algorithms》(《算法导论》)的朋友们应该还记得,在讲到归并排序(Merge Sort)和快速排序的时候,有一种很简单又很有效率的思路就是“分而治之”,即“分治法”。而Fork Join的思路也是同理,只不过划分之后的任务更适合分派给不同的计算资源,可以并行的完成任务。



当计算分别完成之后,最后再合并回来。

简单来看,就是一个递归的分解和合并,直到任务小到可以接受的程度。

2. Fork Join 设计要点

Fork Join设计出来就是为了提高任务完成的效率,围绕这个目标,有一些要点是设计中需要考虑的,下面就给出一些要点。

线程的管理和线程的单纯性。基于如上的设计思路,我们可以看到子任务之间的相关性是相对比较简单的,可以并行处理。为了提高效率,并不需要重量级的线程结构和对应的线程维护,线程实现简单就好,满足需求即可,降低维护成本。

队列机制,硬件支持一定是比较有限的,那么分解的任务应该用队列维护起来,一个好的队列设计是很有必要的。

工作窃取”,也就是设计论文原文中提到的 Work Stealing 。对于负载比较轻的线程,可以帮助负载较重的执行线程分担任务。

对于使用Fork Join的开发者来讲,需要注意:

可用线程数和硬件支持。线程这东西,也是有开销的东西,绝对不是越多越好,尤其在硬件基础有限的情况下。

任务分解的粒度。和前者有关系,就是分解的任务,“小”到什么程度是可以接受的,不可再分。

3. Fork Join数据结构支持

按照如上设计,分解执行一个大的任务,Fork Join至少需要考虑如下一些数据结构。

轻量级的线程结构。

维护线程的线程池,负责线程的创建,数量维护和任务管理。维护任务,并支持Work Stealing的双端队列。

如下图。



对于子任务的分解,可以从base端取出分解再放入,而对于WorkStealing则可以从top端取出,放入其他队列的尾部。

原文链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息