在具有1GB RAM的机器上对1TB文件进行排序

时间:2011-12-22 03:03:20

标签: c++ sorting memory-management external-sorting

这个问题似乎很容易,但我无法理解它背后的真正工作。 我知道人们会说,分解成512 Megs的块并将它们排序为使用Map reduce的Merge Sort。

所以这是我的实际问题:

假设我将文件分成512 Megs块,然后发送到不同的主机进行排序。 假设这些机器使用了Merge Sort。 现在说,我有2000台机器每个排序2000,512兆块。现在当我合并它们时,它是如何工作的?尺寸不会继续增加吗?例如,合并两个512兆的将产生1024Megs,这是我的RAM的大小,那么这将如何工作?任何机器都不能将超过512兆块的块与另一块块合并,因为那么大小> 1 GB。

如果在合并结束时我将能够将两个0.5 TB的块与另一个0.5 TB的块合并。虚拟内存的概念是否会在这里发挥作用?

我在这里澄清我的基本知识,我希望我正确地问这个非常重要的问题(正确)。另外,谁应该做这个合并(排序后)?我的机器或那些2000机器中的一些?

5 个答案:

答案 0 :(得分:6)

合并方式的简短版本如下:

1)您为要合并的每台计算机创建一个包含一个插槽的表。

2)你问每台机器他们还没有给你的最低入口。

3)从表中删除最低值的条目,输出它,并要求该机器用它尚未给你的最低条目重新填充慢速,如果机器没有条目,则将插槽留空。

4)重复步骤3,直到表格为空。

这允许您从N个机器合并,一次只存储N个条目。当然,您可以轻松优化它以保存每台机器的M个条目。在这种情况下,您需要存储N * M个条目,当一个插槽为空时,要求该机器输入M个条目。

答案 1 :(得分:4)

  

现在说,我有2000台机器,每台机器分拣2000个,512兆块。现在   当我把它们合并回来时,它是如何工作的?尺寸不会继续   再次增加?例如,合并两个512兆的将产生1024Megs   这是我的RAM的大小所以这将如何工作?任何机器都不能   将一块超过512兆块的块与另一块块合并,因为   那么尺寸> 1 GB。

这不是实际的mergesort实现的工作原理。关于mergesort(和相关的排序算法)的一个很酷的事情是你不需要在内存中拥有整个数据集来使它工作。合并时,您只需要一次读入内存中的一小部分文件,然后很快就会写出来。

换句话说,您不需要随机访问mergesort。如果它不适合这个不错的财产,那么sort the data on tape drives就不可能使用当时可用的技术。磁带驱动器当然不是随机访问介质,然后以千字节为单位测量RAM。

答案 2 :(得分:4)

此问题可以简化为更简单的问题。这个问题旨在迫使您采取一种方法。这是:

  • 拿起块= ~1GB,排序&将它们存储为单独的排序文件。
  • 您最终在文件系统上输入了1000个1GB的文件。
  • 现在,它只是将k排序数组合并为新数组的问题。

    合并k-sorted数组需要您一次维护一个包含k个元素的最小堆(Priority Queue)。

即。在我们的案例中, k = 1000 (文件)。 ( 1GB内存可以存储1000个数字

因此,请保持从优先级队列中弹出元素并保存到磁盘。

您将有一个新文件,按大小1TB排序。

参考:http://www.geeksforgeeks.org/merge-k-sorted-arrays/

<强>更新

PS:可在具有1 GB RAM且具有更好数据结构的单台计算机上完成

合并可以在少于 O(N)空间的情况下使用优先级队列完成,即 O(K)空间,即问题的核心。

答案 3 :(得分:3)

这是一种应该有效的理论方法。假设你有2000个512mb文件,准备创建一个1TB文件。

如果您只是遍历每个文件,找到哪个文件具有最低的FIRST值,然后将其移动到您的目标文件中,然后重复,那么您将按顺序完成所有操作。 RAM使用量应该很小,因为您一次不需要打开多行。

显然你应该能够优化它 - 保持RAM中每个文件的第一行,它应该更快一些。

答案 4 :(得分:1)

合并排序的好处是你不需要随机访问;顺序访问会做。当数据集不适合内存时,这就是它的完美解决方案。

单个合并传递需要2个(或更多)输入并产生一个输出。您只需将输入组合到输出中,直到只剩下一个文件。