我在64位Linux机器上使用gcc 4.7.2。
我有20个大的排序二进制POD文件,我需要在外部合并排序中作为最终合并的一部分阅读。
通常,在mmap
写入磁盘之前,我会multiset<T,LessThan>
所有要读取的文件并使用mmap
来管理从小到大的合并排序。
但是,我意识到,如果我在每个文件上保留std::mutex
,我可以创建第二个线程,向后读取文件,同时从大到小排序。如果我事先决定第一个线程将采用正好n / 2个元素而第二个线程将采用其余的元素,那么我将不需要在输出端使用互斥锁。
在这种特殊情况下,读取锁定争用,平均可能会发生在20中,因此这是可以接受的。
现在,这是我的问题。在第一种情况下,很明显我应该使用madvise
,调用MADV_SEQUENTIAL
,但我不知道我应该为第二种情况做什么,我正在向后读取文件。
我在手册页中看不到MADV_REVERSE
。我应该使用MADV_NORMAL
还是根本不打电话给madvise
?
回想一下,当数据量太大而无法放入内存时,需要进行外部排序。因此,我们留下了一个更复杂的算法,将磁盘用作临时存储。划分和征服算法通常涉及分解数据,进行部分排序,然后合并部分排序。
我的外部合并排序步骤
std::multiset<T,LessThan> buff_fwd;
,为反向线程实例化std::multiset<T,GreaterThan> buff_rev
。有些人喜欢在这里使用优先级队列,但实质上,插入插件容器在这里可以使用。答案 0 :(得分:1)
我建议:
MADV_RANDOM
防止无用的预读(方向错误)。