优化文件读写

时间:2011-01-28 13:13:19

标签: c++ c file-io

我有这段代码将64MB的二进制数据读入内存:


#define SIZE 8192
char* readFromFile(FILE* fp)
{
  char* memBlk = new char[SIZE*SIZE];
  fread(memBlk, 1, SIZE*SIZE, fp);
  return memBlk;
}

int main()
{
  FILE* fp = fopen("/some_path/file.bin", "rb+");
  char* read_data = readFromFile(fp);
  // do something on read data
  // EDIT: It is a matrix, so I would be reading row-wise.
  delete[] memBlk;
  fclose(fp);
}

当我独立使用此代码时,运行时间不到1秒。 但是,当我将完全相同的代码(仅用于基准测试)放在我们的一个应用程序中时,运行时间为146秒。该应用程序非常笨重,内存使用量高达5G。

其中一些可以用当前的内存使用情况,缓存未命中率和其他因素来解释,但差异为146的声音对我来说是不合理的。

有人可以解释一下吗?

内存映射可以提高性能。我们也欢迎任何其他建议。

感谢。

机器信息: Linux my_mach 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:56:44 EST 2007 x86_64 x86_64 x86_64 GNU/Linux

编辑:

感谢您的回答,但是,我错过了实际上我插入的地方本身被称为25次的事实,因此它不是146的因素。

无论如何,答案很有帮助,谢谢你的时间。

3 个答案:

答案 0 :(得分:3)

看起来您的代码所需的额外内存会导致应用程序中的抖动,这可能已经在极限运行。

如果你想对文件“做点什么”,你可以:

  • 以块状方式处理文件

  • 如果您需要更复杂的访问权限,请在操作系统上使用mmap()或类似的内存映射技术将文件映射到内存

    mmap使用缓冲区缓存作为后备存储,将内容分页到交换空间的文件本身内容中。使用mmap通常是访问文件最快的最简单方法。虽然不是完全可移植的(它可以在UNIX类似的OS组中移植,例如所有BSD,Linux,Solaris和MacOSX)

您没有指定“做某事”的访问模式,因此很难推荐某些特定的技术

答案 1 :(得分:3)

5G是一个巨大的内存,你确定你有这么多的物理内存。如果不是因为146差异可能是由于交换到磁盘以尝试释放内存。

您还应该考虑在64位计算机上使用64位操作系统。

答案 2 :(得分:1)

在一个连续的块中,该进程可能没有64MB的免费存储空间。您是否可以尝试将64MB缓冲区拆分为一系列较小的块(例如64K或256K),看看这是否有助于提高性能?