提高C ++程序的I / O性能[外部合并排序]

时间:2010-04-23 01:43:42

标签: c++ performance mergesort

我目前正在开发一个涉及使用替换选择和k-way合并进行外部合并排序的项目。我用C ++实现了这个项目[在linux上运行]。它非常简单,现在只处理固定大小的记录。

阅读&写我使用(i / o)fstream类。执行程序几次迭代后,我注意到了

  • I / O读取大小超过4K(典型块大小)的请求的块。实际上,缓冲区大小大于4K会导致性能下降。
  • 输出操作似乎不需要缓冲,linux似乎负责缓冲输出。所以我发出一个写(记录)而不是维护写入的特殊缓冲区,然后使用write(records [])立即刷新它们。

但是应用程序的性能似乎并不高。我怎样才能提高性能?我应该维护特殊的I / O线程来处理读取块吗?还是现有的C ++类已经提供了这种抽象?(像java中的BufferedInputStream)

3 个答案:

答案 0 :(得分:3)

使用mmap最简单地完成这种高性能I / O.这使内核可以更自由地执行I / O并为您的应用安排CPU时间。例如,当您使用ifstream读取1 MB时,内核只能在读取所有数据时返回。但是使用mmap(),数据可以在可用时以递增方式返回。

但是,您应该了解这是如何发生的。仅仅因为数据似乎在RAM中并不意味着您应该将其视为随机可访问。请勿将其提供给std::sort。这将触摸mmap的区域的随机部分,导致页面错误左右中心。因此,您将导致重磁盘寻求解决随机页面错误。相反,mmap()两个输入并合并它们。因为mmap命令告诉内核将来需要哪些数据,所以内核会尽可能快地为您提供数据,并且当它暂时没有数据时,您的合并排序会出现页面错误(即停止)。

答案 1 :(得分:2)

查看使用C低级IO库。 http://www.linuxtopia.org/online_books/programming_books/gnu_libc_guide/Low_002dLevel-I_002fO.html 要么 ftp://ftp2.developpez.be/developps/linux/alp/alp-apB-low-level-io.pdf

在很久以前的Windows中,我使用低级IO打开比使用fopen快10倍。

也许你不会获得相同的性能优势,我知道这将是一件事。

答案 2 :(得分:1)

与plain-C I / O相比,Streams以其性能问题而闻名。事实上,它们表现为“易于使用且适合不同情况”,但缺乏性能。在您的情况下我会做的是切换到C风格的I / O,分析,然后根据分析结果进行操作。