优化文件的读取和写入

问题描述:

我有这样的代码读取二进制数据的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的因素。

不管怎样,答案是有帮助的,谢谢你的时间。

+2

为什么使用动态分配的内存来存储固定大小的缓冲区? – 2011-01-28 13:16:53

+1

@Blagovest:你并不是建议在*堆栈*中存储64MB的数据,对吗? – thkala 2011-01-28 13:18:56

+0

“// ......做些什么?”呢? – 2011-01-28 13:19:17

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

如果你想“有所作为”与文件,您可以:

  • 处理文件列块

  • 使用mmap()或操作系统上的一些类似的内存映射技术来地图如果您需要更复杂的访问,则将文件存入内存

    mmap ing使用缓冲区缓存作为后备存储将页面内容分页到交换空间的文件本身insead中。使用mmap通常是访问文件的最简单方法。虽然不是完全可移植的(它可以制成便携式在OS'es的UNIX组的一致好评例如,所有的BSD,Linux,Solaris和MacOSX的和)

你并没有说明具体的访问模式“做什么”会因此很难推荐一些特定的技术

该过程可能没有64MB的免费商店在一个连续的块中随时可用。你可以尝试将64MB缓冲区分成一些小块,比如64K或256K大小的块,然后看看它是否有助于提高性能?

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

你也应该看看在64位机器上使用64位操作系统。