[英]Good C++ array class for dealing with large arrays of data in a fast and memory efficient way?
在前面有关堆使用限制的问题之后 ,我正在寻找一个好的标准C ++类,以一种既能节省内存又能提高速度的方式处理大型数据。 我一直在使用单个malloc / HealAlloc分配数组,但是在使用各种调用多次尝试之后,请避免犯下堆碎片的问题。 因此,除了移植到64位之外,我得出的结论是要使用一种机制,使我能够拥有一个跨多个较小的内存片段的大型阵列。 我不希望为每个元素分配内存,因为这会导致内存效率低下,因此计划是编写一个重写[]运算符的类,然后根据索引选择一个合适的元素。 是否已经有一个不错的班级来做到这一点,还是我最好自己动手做?
根据我的理解和一些谷歌搜索 ,从理论上讲32位Windows进程应该能够处理高达2GB的内存。 现在假设我已经安装了2GB,并且其他各种进程和服务都占用了大约400MB,那么您认为我的程序可以从堆中合理地获得多少可用内存?
我目前正在使用各种口味的Visual C ++。
编辑根据Poita的帖子,我已经在VS2008上使用以下测试尝试了std :: deque ;
#include <deque>
using namespace std;
struct V
{
double data[11];
};
struct T
{
long data[8];
};
void dequeTest()
{
deque<V> VQ;
deque<T> TQ;
V defV;
T defT;
VQ.resize(4000000,defV);
TQ.resize(8000000,defT);
}
以上数据的总内存为608MB,如果我使用直接malloc或HeapAlloc,则需要不到1秒的时间。 双端队列调整大小最初占用了950MB,然后慢慢开始回落。 15分钟后,dequeTest()完成,仅使用6MB的内存显示该进程,这可能与运行时有关。 我还尝试使用各种推送选项填充双端队列,但是性能太差了,我不得不提早开始。 我可能会提供比defualt更好的分配器,以获得更好的响应,但是表面上deque不是此工作的课程。 请注意,这也可能与deque的MS VS2008实现有关,因为此类中似乎有很多与性能有关的实现。
我认为是时候编写自己的大型数组类了。
第二次修改:使用以下命令分配较小的数量会立即产生1.875GB;
#define TenMB 1024*1024*10
void SmallerAllocs()
{
size_t Total = 0;
LPVOID p[200];
for (int i = 0; i < 200; i++)
{
p[i] = malloc(TenMB);
if (p[i])
Total += TenMB; else
break;
}
CString Msg;
Msg.Format("Allocated %0.3lfGB",Total/(1024.0*1024.0*1024.0));
AfxMessageBox(Msg,MB_OK);
}
最终编辑我决定接受Poita的帖子及其后的各种评论,不是因为我将直接使用deque类,而是在随后的评论中将数组更多用作卡片概念。 基于每个块中固定数量的元素,这应该很容易用O(1)随机元素访问来实现,这正是我所需要的。 感谢大家的反馈!
您是否尝试过使用std::deque
? 与使用一个巨大堆分配的std::vector
不同, deque
通常以小块分配,但仍通过operator[]
提供摊销的固定时间索引。
从程序的角度来看,无论系统中发生了什么事情,启动时始终有2GB可用空间。 我认为Windows无法提供一种方法来检测是否有内存被调出到磁盘上。 就数据结构而言,听起来好像您正在描述类似于在STL中实现双端队列的方式。
std :: deque确实可以满足您的描述,但通常以OS页面大小的粒度(即,它分配的块通常为4 kB)为准。
如果您对deque的默认性能不满意,则可以编写一个捕获更大块的自定义分配器-即一次获取1 MB或更多。
正如其他人所说,您的进程的虚拟地址空间完全独立于所有其他进程,因此无论系统中发生了什么,您都可以寻址2GB。 操作系统将根据需要与磁盘交换内存页,以适应已安装内存量和所有争用该内存的进程的限制。 这将在4 kB页面大小时发生,与您的块大小无关。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.