C++ 中的一个非常大的 3D 数组

A REALLY huge 3D array in C++

关键是:我正在编写一种愚蠢的程序,它获取手绘声波的 BMP 图像并将其转换为实际声音。它工作正常,但我正在寻找一种将整个图像加载到内存中的好方法。我目前使用 std::vector 加载一个 500 MB 的图像,只是为了在任务管理器中看到该进程分配了太多我的 8GB RAM,以至于它需要额外的分页(停止在 6 GB 左右)。我想这是某种开销...

我的问题是:是否有更节省内存的方法来分配巨大的 3D 数组?是否有任何速度高效的方法来逐字节读取大文件? (我在等待它加载时正在写这篇文章,大约 50 分钟后它是 85%)

编辑 OS 是 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

你所说的3D数组更多的是包含RGB元素的2D数组,500Mb确实不是'REALLY huge'那些日子

应避免使用 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位图数据,我强烈建议你看一下Handmade Hero,它从一开始就涵盖了这个主题,我相信这一集:https://www.youtube.com/watch?v=ofMJUSchXwo