Data Decomposition
1.1 问题
如何将待解决的问题的数据分解为能够并行运行的数据单元(units)?
1.2 上下文
并行算法的设计者必须首先详细了解待解决的问题,除此之外,还必须识别如下几个关键因素:
1)计算强相关的部分:待解决问题中的哪部分需要进行大量运算;
2)关键数据结构:主要是对什么数据进行运算;如何进行运算。
当基本问题理解后,设计师必须考虑解决问题的需要完成哪些任务以及这些任务中包含哪些数据。为了创建并行算法,关键不是要进行哪种分解,而是首先从哪种分解开始,任务分解和数据分解都要进行。
什么情况下该首先采用基于数据的分解方式呢?如果存在以下场景,则从数据分解开始时比较好的选择:
1)待解决问题中计算强相关的部分都是围绕数据进行组织的;
2)同样的操作应用到数据结构的不同部分;
1.3 考虑因素
1.3.1 灵活
此时考虑灵活性主要是为了能够让设计能够满足不同的实现需求,这里的实现就是具体采用的技术,例如采用Java编程,采用多CPU的小型机运行等,如果客户不强制要求,在这个阶段就不要限制这些。当然如果问题里面本身已经包含了这种实现,那就必须考虑这种实现的限制了。例如客户要求只能运行在小型机上面,那么设计的时候就需要考虑小型机的特点对人物分解的影响了。
1.3.2 有效
并行程序只有在随着并行计算机的规模增大时效率能够按比例增长才有意义。对于任务分解来说,这就意味着我们需要足够的任务来使得所有计算机都处于忙碌的状态。
通过使每个任务有足够的工作(Work)来弥补管理任务间的依赖带来的效率损失才能达到这点。当然,效率提升会带来灵活性的降低。
1.3.3 简单
再怎么好的程序也要人维护吧,所以再怎么复杂怎么好都要考虑怎么维护。
以上三种因素互相制约,具体怎么平衡,还是要看设计师的水平。
1.4 解决方法
如果已经基于任务进行了分解,则可以针对每个任务进行数据分解。如果定义良好且清晰的数据能够和每个人物关联,则数据分解就简单了。
如果我们从数据分解开始进行分解,则这个时候还没有任务,因此我们不能盯着任务进行分解了,而应该盯住最主要的数据结构,然后考虑如何将数据结构分解为数据块,使得针对数据块的操作能够并行。一些常见的样例如下:
1)线性数据结构:可以采用“分段方式”对数据进行分解,针对不同的数据段进行并行操作;如果是一个多维的数据结构,则可以采用多种方式进行分解:按列、按行、按数据块。
2)递归数据结构:可以采用“递归方式”对数据进行分解,所谓“递归方式”就是指针对数据的一部分操作和针对整个数据的操作原理上是一样的。典型的样例就是“树”这种数据结构了,每个子树其实都是一颗树,可以先对子树进行计算,然后将子树合并起来又是一颗树,这样就能够通过并行来完成树的计算了。