C++ 存储大量数据的数据结构?
在我的应用程序中,我必须从一组图像(MRC图像)中加载volumedata,并将像素数据保存在内存中(图像是灰度的,因此每个像素一个字节) 我的开发环境是QT framework、Windows的MinGW和Linux的GCC 目前,我使用一个简单的数据结构将volumedata存储为:C++ 存储大量数据的数据结构?,c++,memory,data-structures,dynamic-memory-allocation,C++,Memory,Data Structures,Dynamic Memory Allocation,在我的应用程序中,我必须从一组图像(MRC图像)中加载volumedata,并将像素数据保存在内存中(图像是灰度的,因此每个像素一个字节) 我的开发环境是QT framework、Windows的MinGW和Linux的GCC 目前,我使用一个简单的数据结构将volumedata存储为: unsigned char *volumeData; 然后做一个巨大的分配,如下所示 volumeData=new unsigned char[imageXsize * imageYsize * numofI
unsigned char *volumeData;
然后做一个巨大的分配,如下所示
volumeData=new unsigned char[imageXsize * imageYsize * numofImages];
以下是访问给定平面中图像数据的重要方法,例如
unsigned char* getXYPlaneSlice(int z_value);
unsigned char* getYZPlaneSlice(int x_value);
unsigned char* getZXPlaneSlice(int y_value);
通过我简单的数据结构,很容易实现上述方法
但我们将来可能需要将卷大小调整为2000x2000x1000(~3.7Gb),而当前的数据结构将无法处理如此庞大的数据
提前感谢。64位可能是处理此问题的最简单方法。。。让操作系统在使用页面时出错。否则,在不了解数据访问模式的情况下,很难给出很多建议。如果您定期扫描图像以查找相同像素坐标下的值,那么说拥有指向图像的指针以按需保存和重新加载是毫无意义的
对于撤消数据,您可以按照建议保留完整备份副本,也可以尝试执行撤消操作,以查看所做的更改并负责找到有效的实现。例如,如果您刚刚翻转了位,那么这是非破坏性的,您只需要对同一位翻转操作使用一个函子来撤消更改。如果将所有像素设置为同一色调是一个常见操作(例如填充、清除),那么您可以使用一个布尔值和一个像素对图像状态进行编码,并使用完整的缓冲区进行撤消。我想您应该看看。这是一种二进制格式,用于存储从望远镜、物理实验和基因测序机等设备收集的大量数据。使用这种方法的好处很多,但有三个直接的想法:(1)经过测试,(2)支持hyperslab选择,以及(3)免费获得压缩
有C/C++、java、python和matlab库可用 > P> >一种选择,我认为是内存映射,而不是映射所有图像,保持一个链接列表的图像是懒惰加载。当过滤器在图像列表中工作时,根据需要加载。在加载阶段,映射一个大小相同的匿名(或某个固定临时文件)块,并将映像复制到该块作为备份。在应用筛选器时,只需备份到此副本。如上@Tony所述,64位是您的最佳选择,对于多平台内存映射文件,请查看boost interprocess。您可以使用内存映射文件管理内存有限的大型数据集。但是,如果文件大小为4GB,则建议使用64位。boost项目有一个很好的多平台内存映射库,它的性能非常接近您所需要的 http://www.boost.org/doc/libs/1_44_0/libs/iostreams/doc/classes/mapped_file.html 让你开始。下面是一些示例代码--
#包括
boost::iostreams::映射的\u文件\u源输入\u源;
输入_source.open(std::string(argv[1]);
const char*data=input_source.data();
long size=input_source.size();
输入_source.close();
谢谢,
Nathan您可以使用两级结构: 指向单个图像或(更好的)一组图像的指针数组。 因此,您可以将20个图像保存在一个内存块中,并将指向20个图像块的指针放入数组中。 在进行随机访问时,这仍然很快(与链表相比) 然后,您可以实现一个简单的分页算法:首先,数组中的所有指针都是空的。首次访问图像块时,将该块的20个图像加载到内存中,并将指针写入数组。 下次访问这些图像时不会加载任何内容 如果由于加载和加载了许多图像块而导致内存不足,则可以删除使用最少的图像块(应在指针旁边添加第二个字段,在该字段中输入每次加载图像块时计数的计数器值)。计数器最低的图像块是使用最少的图像块,可以删除(内存被重新用于新块,指针设置为NULL)。请查看。我不是it专家,但从its和,它允许您自然地将数据映射到3D(+1D用于时间/版本控制)数组中,如下所示:
CREATE ARRAY Pixels [
x INT,
y INT,
z INT,
version INT
] (
pixel INT
);
要实现查询,请执行以下操作:
Slice (Pixels, z = 3, version = 1);
为了避免在仅更改部分数据时重复数据,不需要为版本1填充整个阵列,因为SciDB支持稀疏阵列。然后,当需要加载最新数据时,可以使用version=0
加载以获取旧版本,然后
Slice (Pixels, z = 3, version = 1);