并行计算

并行计算:用很多台电脑去共同完成计算,每一个参与计算的电脑叫节点。

并行计算的方法(3步):

1、  将数据拆分到每个节点上

思考:如何拆分,一共有几个节点,每个节点能承受的数量是多大,拆分能保证每个节点独立的计算(不能一个节点上的数据依赖另一个节点的数据)

2、  每个节点并行的计算出结果

思考:每个节点要算出一个什么结果,最后来汇总

3、  将结果汇总

思考:通过每个节点的结果来汇总出最后想要的结果。

扫描二维码关注公众号,回复: 2428065 查看本文章

外部排序(如何排序10G个元素)

方法:扩展的归并排序

归并排序:将数据分为左右两半,分别归并排序,再把两个有序数据归并。

如何归并:

         [1,3,6,7],[1,2,3,5]->1                

         [3,6,7],[1,2,3,5]->1

         [3,6,7],[2,3,5]->2

         [3,6,7],[3,5]->3

         …..

两边最小的数作比较,最小的数是哪一个,把最小的放出来,当两边一样大的时候,选择左边那个。

外部排序:

并行计算的思路:把数据分成很多段,第一步,把数据进行切分,每一段送给一个节点去进行排序,每一段数据量小到在内存里放得下,然后各节点做普通排序就可以了(归并、快排…),排完之后,每个节点的结果都是有序的序列。

归并节点:再每个序列里一直选最小的数出来

归并节点的实现:

K路归并:

优化出一个堆

堆的好处:树根是最小的数(在1拿走后,看左右儿子,谁小谁就是新的树根,然后递归2的左右儿子)(顺着树根一直比下去,logN就能取出)

K路归并-库里的另一种实现:PriorityQueue(原理:优先队列)

分别把最小的push()进去,然后pop()一个补一个

 

把一部分数据放入内存,可以作为缓冲区,不用每次补元素的时候都从硬盘取过来(这样比较慢)。

归并节点非常复杂,有个归并算法,还有PriorityQueue的数据结构要维护,从数据源取数据还不是一口气拿的,有时候从内存里拿,有时候从硬盘上拿。所以归并节点的程序写出来会很复杂,很难写。还好有Iterable<T>接口

归并:使用Iterable<T>接口

1、  可以不断获取下一个元素的能力

2、  元素存储/获取方式被抽象,与归并节点无关。

3、  Iterable<T> merge(List<Iterable<T>>sortedDate);

结构:

归并数据源来自Iterable<T>.next()

先充每一个数据源调用next获取他们最小的元素,加到PriorityQueue里面去,然后不断从PriorityQueue里面pop()一个元素,pop()完后再获得这个pop()元素的数据源,以此来获得下一个元素。

1、  如果缓冲区空,读取下一批元素放入缓冲区

2、  给出缓冲区第一个元素

3、  可配置项:缓冲区大小,如何获取下一批元素

好处:归并节点就不需要考虑缓冲区的情况,只要不断跟每个数据源调next即可

猜你喜欢

转载自blog.csdn.net/qq_37117521/article/details/80891468