将大量二进制数据加载到RAM中

Tia*_*.SR 3 c++ memory-management vector c++11

我的应用程序需要从MegaBytes加载到几十千兆字节的二进制数据(多个文件)到RAM中.经过一番搜索,我决定使用std::vector<unsigned char>这个目的,虽然我不确定它是最好的选择.

我会为每个文件使用一个向量.由于应用程序以前知道文件大小,它会调用reserve()为它分配内存.有时候应用程序可能需要完全读取一个文件,而在其他一些文件中只需要部分文件和vector的迭代器就可以了.它可能需要卸载从RAM中的文件,并在地方放其他的,std::vector::swap()并且std::vector::shrink_to_fit()将是非常有用的.我不想在处理低级内存分配方面付出艰苦的努力(否则会与C一起).

我有一些问题:

  • 应用程序必须从列表中加载更多文件到RAM中.怎么知道是否有足够的内存空间来加载一个文件?它应该打电话reserve()并寻找错误吗?怎么样?引用仅说reserve()当请求的大小大于时抛出异常std::vector::max_size.
  • std::vector<unsigned char>适用于获得这种大量的二进制数据到RAM?我担心std::vector::max_size,因为它的参考说它的价值将取决于系统或实施限制.我认为系统限制是免费RAM,是不是?所以,没问题.但是实现限制怎么样?是否存在任何可能妨碍我做我想做的实现?案例肯定,请给我一个替代方案.
  • 如果我想使用整个RAM空间,除了N GigaBytes,该怎么办?sysinfo()如果可以加载每个文件,是否真的可以使用和推断基于可用RAM 的最佳方式?

Obs.:应用程序的这一部分必须能够获得更高的性能(低处理时间/ CPU使用率和RAM消耗).我很感激你的帮助.

eer*_*ika 6

怎么知道是否有足够的内存空间来加载一个文件?

你不会事先知道.将加载过程包装在try-catch中.如果内存耗尽,则std::bad_alloc抛出a(假设您使用默认分配器).假设内存在加载代码中足够,并处理异常处理程序中缺少的内存.

但是实现限制怎么样?......有什么关于实施可以阻止我做我想做的事情吗?

您可以std::vector::max_size在运行时检查以进行验证.

如果程序是使用64位字大小编译的,那么向量很可能具有足够的max_size几百GB.


应用程序的这一部分必须获得更多性能

这与之相冲突

我不想在处理低级内存分配方面付出艰辛的努力

但是如果低级内存对于性能来说是值得的,那么你可以将文件内存映射到内存中.


我已经阅读了一些SO问题,以避免它们出现在需要高性能的应用程序上,并且更喜欢处理返回值,errno等

不幸的是,如果您使用标准容器,则不能选择非投掷内存分配.如果您对异常过敏,那么您必须使用向量的另一个实现 - 或者您决定使用的任何容器.但是,您不需要任何带有mmap的容器.

处理异常会不会破坏性能?

幸运的是,与从磁盘读取数百GB相比,异常的运行时成本是微不足道的.

可能最好运行sysinfo()并在加载文件之前检查空闲RAM吗?

sysinfo 调用可能比处理异常要慢(我没有测量,这只是一个猜想) - 并且它不会告诉你可能存在的特定于进程的限制.

而且,重复尝试加载文件,捕获异常并尝试加载较小的文件(需要递归?)看起来很难并且代价高昂.

不需要递归.如果您愿意,可以使用它; 它可以用尾调用来编写,可以优化掉.


关于内存映射:我前一段时间看过它,发现无聊处理.需要使用C的open()和所有内容,然后再告诉std :: fstream.

映射内存后,它比使用起来更容易std::fstream.您可以跳过复制到矢量部分,只需使用映射的内存,就好像它是一个已经存在于内存中的数组一样.

看起来使用std :: fstream部分读取文件的最佳方法是派生std :: streambuf

我不明白为什么你需要得到任何东西.只是std::basic_fstream::seekg()用来跳到你想要阅读的部分.