并行外部排序的复杂性是什么

时间:2019-02-16 09:53:50

标签: algorithm sorting external-sorting

我想知道进行并行外部排序时的复杂性是什么。

假设我有大数组N和有限的内存。 F.e 10亿个条目要排序,而条目存储器中只有1k。

在这种情况下,我已使用并行线程将大数组拆分为K个排序的文件,块大小为B,并保存在磁盘中。

从所有文件读取后,使用priprityQueue和线程合并回新数组。

我需要用大O表示法计算复杂度。

如果我要使用多进程,那么说N个处理器会给复杂性带来什么?

is it ~O(N/10 * log N) ?? 

谢谢

1 个答案:

答案 0 :(得分:1)

无论处理器数量和/或外部驱动器数量如何,时间复杂度将为O(n log(n))。总时间为T(n / a logb(n)),但是由于a和b是常数,因此即使时间说快10倍,时间复杂度也保持在O(n log(n))不变。

我不清楚您所说的“并行”外部排序是什么意思。我假设有多个内核或多个处理器,但是是否还有多个驱动器?是否所有N个内核或处理器共享仅容纳1k个元素的相同内存,或者每个内核或处理器都具有自己的“ 1k”内存(实际上具有“ Nk”个内存)?


一般来说,外部合并排序

在初始阶段,将按大小为B的块(1k个元素)读取输入数组,进行排序,然后将其写入K个排序的文件。此初始遍历的最终结果是K个大小为B的分类文件(1k个元素)。其余所有通道将重复合并排序的文件,直到生成单个排序的文件。

通常,初始遍历是cpu绑定的,使用多个内核或处理器对大小为B的每个块进行排序将减少时间。初始遍历可以使用任何排序方法或任何稳定的排序方法。

对于合并阶段,能够与执行合并操作并行执行I / O将减少时间。与使用异步I / O进行相同的操作相比,使用多线程将I / O与合并操作进行重叠将减少时间,并且更简单。我不知道使用多线程来减少k路合并操作时间的方法。

对于k向合并,将以B /(k + 1)大小的较小块读取文件。这样就可以为k向合并操作提供k个输入缓冲区和1个输出缓冲区。

对于硬盘驱动器,随机访问开销是一个问题,例如传输速率为200 MB / s,平均随机访问开销为0.01秒,这与传输2 MB的时间相同。如果缓冲区大小为2 MB,则随机访问开销将传输速率有效降低了1/2到〜100 MB / s。如果缓冲区大小为8 KB,则随机访问开销可将传输速率有效降低1/250到〜0.8 MB / s。使用较小的缓冲区,由于随机访问的开销,两路合并会更快。

对于非服务器设置中的SSD,通常没有命令排队,并且命令开销在读取时约为.0001秒,在写入时约为.000025秒。 Sata接口固态硬盘的传输速率约为500 MB / s。如果缓冲区大小为2MB,则命令开销微不足道。如果缓冲区大小为4KB,则读取速率降低1 / 12.5至〜40 MB / s,写入速率降低1 / 3.125至〜160 MB / s。因此,如果缓冲区大小足够小,再次进行2路合并将更快。

在PC上,这些较小的缓冲方案是不可能的。在使用gnu进行大型文本文件排序的情况下,使用默认设置,它会分配1GB以上的RAM,并在初始遍历时创建1GB排序的文件,并进行16向合并,因此缓冲区大小为1GB / 17〜 = 60 MB。 (17是用于16个输入缓冲区,1个输出缓冲区)。


考虑所有数据都适合内存且内存由k个排序列表组成的情况。合并列表的时间复杂度为O(n log(k)),无论是否使用2向合并排序,以任何顺序合并列表对或是否使用k向合并排序来合并所有列表一口气列出。

我在我的系统上进行了一些实际的测试,即Intel 3770K 3.5GHz,Windows 7 Pro 64位。对于基于堆的k路合并,k = 16,传输速率〜235 MB / sec,k = 4,传输速率〜495 MB / sec。对于非堆4路合并,传输速率〜1195 MB /秒。硬盘传输速率通常为70 MB /秒至200 MB /秒。典型的SSD传输速率约为500 MB /秒。昂贵的服务器类型固态硬盘(SAS或PCIe)读取速度约为2GB /秒,写入速度约为1.2GB /秒。