Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 优化文件读写_C++_C_File Io - Fatal编程技术网

C++ 优化文件读写

C++ 优化文件读写,c++,c,file-io,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 =

我有以下代码可以将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星期三11月7日13:56:44 EST 2007 x86_64 x86_64 x86_64 GNU/Linux

编辑:

谢谢你的回答,但是,我错过了一个事实,实际上我插入的地方本身被调用了25次,所以它不完全是146的一个因子


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

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

如果要对文件执行某些操作,可以:

分块处理文件

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

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


您没有指定要执行的访问模式,因此很难推荐某些特定的技术

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

如果要对文件执行某些操作,可以:

分块处理文件

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

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


您没有指定要执行的访问模式,因此很难推荐某些特定的技术

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

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

5G是一个巨大的内存量,您确定机上有这么多物理内存吗。如果不是,差异的因素可能是由于交换到磁盘以释放内存


您可能还应该考虑在64位机器上使用64位操作系统

5G是一个巨大的内存量,您确定板上有这么多物理内存吗。如果不是,差异的因素可能是由于交换到磁盘以释放内存


您可能还应该考虑在64位机器上使用64位操作系统

为什么要使用动态分配的内存来存储固定大小的缓冲区?@Blagovest:你不是建议在堆栈中存储64MB的数据,是吗?该/。。用它做点什么。。是吗?@thkala:当然不是,静态变量会更有效率。这是在32位还是64位操作系统上?为什么要使用动态分配的内存来存储固定大小的缓冲区?@Blagovest:你不是建议在堆栈中存储64MB的数据,是吗?//。。用它做点什么。。是吗?@thkala:当然不是,静态变量会更有效率。这是在32位还是64位操作系统上?64K分配很可能会在引擎盖下使用mmap。64*M*-除了这个细节,我同意多伦的观点。虽然malloc可能在引擎盖下使用mmap,但它会做的是:1。mmap一些空白页,2。使用不同的页面作为缓冲区缓存,将文件内容复制到这些页面中,3。如果还需要写入内容,请将其复制回文件中。当mmap'ing文件时,只会使用缓冲区缓存来分页文件部分。为了说明我的意思是mmap’ing the file,我将澄清这一点,64K分配最有可能在引擎盖下使用mmap。64*M*-除了这个细节,我同意多伦的观点。虽然malloc可能在引擎盖下使用mmap
至少它可以做到:1。mmap一些空白页,2。使用不同的页面作为缓冲区缓存,将文件内容复制到这些页面中,3。如果还需要写入内容,请将其复制回文件中。当mmap'ing文件时,只会使用缓冲区缓存来分页文件部分。为了说明我的意思是mmap’ing文件,我将澄清这一点,这将直接从操作系统分配,可能是通过mmap,而不是从进程堆。鉴于此,64M块在虚拟内存空间中可能是连续的,但在物理内存中不需要是连续的。如果不是这样,new会抛出std::bad_alloc。@doron:你把K和MB混淆了吗?如果这是一个32位操作系统,进程可能没有64MB的可用地址空间,更不用说空闲存储了。操作系统可能还可以,我承认我在这里猜测,然后尝试重新映射可用的地址空间。如果我们知道操作系统,这会有所帮助。@mAlters:我不确定new是否会马上放弃它。我认为如上所述,我推测一些系统将尝试重新安排地址空间以释放足够大的连续块。我确信这种行为将依赖于操作系统。@Dam正如MSalters所说,如果地址空间中没有放置新内存块的位置,那么new将失败。问题在于性能,我要指出的是堆遍历不是这里的问题。这将直接从操作系统(可能是通过mmap)分配,而不是从进程堆分配。鉴于此,64M块在虚拟内存空间中可能是连续的,但在物理内存中不需要是连续的。如果不是这样,new会抛出std::bad_alloc。@doron:你把K和MB混淆了吗?如果这是一个32位操作系统,进程可能没有64MB的可用地址空间,更不用说空闲存储了。操作系统可能还可以,我承认我在这里猜测,然后尝试重新映射可用的地址空间。如果我们知道操作系统,这会有所帮助。@mAlters:我不确定new是否会马上放弃它。我认为如上所述,我推测一些系统将尝试重新安排地址空间以释放足够大的连续块。我确信这种行为将依赖于操作系统。@Dam正如MSalters所说,如果地址空间中没有放置新内存块的位置,那么new将失败。问题是性能问题,我要指出的是堆遍历不是这里的问题。修订后的问题指出上面的代码本身在1秒内运行,所以不是这一部分导致了减速,所以交换确实是减速的一个可能原因。修订后的问题指出上面的代码本身在1秒内运行,因此,经济放缓并非源于这一部分,因此交换确实是经济放缓的一个可能原因。