关键在于:我正在编写一种愚蠢的程序,它采用手绘声波的BMP图像并将其转换为实际声音。它工作正常,但我正在寻找一种将整个图像加载到内存的好方法。我目前使用std :: vector来加载一个500 MB的图像,只是为了在任务管理器中看到该进程分配了大量的8GB RAM,它需要额外的分页(停止在6 GB左右)。我想这是一种开销......
这是我的问题:是否有一种更节省内存的方式来分配巨大的3D阵列?有没有任何速度有效的方法来逐字节读取大文件? (我在等待它加载时写这个,在50分钟后它是85%)
修改的 操作系统是64位Windows。而且它甚至超过6GB,RAM太小了,因此Windows开始将数组放入页面文件中(我做了一个小百分比指标,当时分配大约80%)..
这是我用于分配的代码
vector <vector<vector<char> > > raster_data; //declaration
raster_data.resize(width);
for(int i=0; i<width; i++)
{
raster_data[i].resize(height);
for(int j=0; j<height; j++)
{
raster_data[i][j].resize(3); //(24bpp=3Bpp)
}
}
所以我不是通过push_back()写数据,而是通过像普通数组一样访问矢量:
raster_data[i][j][k] // in a 3d for loop
答案 0 :(得分:5)
你所谓的3D阵列更像是一个包含RGB元素的二维数组,而那些500Mb实际上并非“非常巨大”。
您应该避免使用std::vector
仅存储3个字节(char
)的方法:
std::vector
ifself消耗的3个字节多得多(你可以通过检查sizeof(std::vector<char>)
的结果知道多少。传统上,对于正在加载2D位图的用例,内存分配在一个块中,然后使用计算索引访问值。
过度简化,这可能是:
struct rgb { // you should check that sizeof(rgb) == 3*sizeof(char), just to be sure
char channels[3];
};
std::vector<rgb> raster_data;
raster_data.resize(width*height);
// channel access :
raster_data[j*width+i][k] = ...;
你可以在这样的缓冲区中有效地读取整个文件内容,但是你需要考虑每行的对齐方式,而且我不能真正说出它是什么(我相信每一行)行在4字节边界上对齐。)
为了让您了解更多关于在C / C ++中处理BMP位图数据的信息,我强烈建议您先看看手工制作的英雄,从一开始就涵盖了这个主题,我相信这一集:https://www.youtube.com/watch?v=ofMJUSchXwo