代码之家  ›  专栏  ›  技术社区  ›  SmacL

好的C++数组类,用于快速、高效地处理大数据数组?

  •  8
  • SmacL  · 技术社区  · 14 年前

    从一个 previous question relating to heap usage restrictions 我正在寻找一个好的C++标准类来处理大量的数据数组,它们既有内存效率又有速度效率。我一直使用一个malloc/healloc来分配数组,但是在多次尝试使用不同的调用之后,总是遇到堆碎片的问题。因此,除了移植到64位之外,我得出的结论是使用一种机制,允许我有一个跨越多个较小内存片段的大数组。我不希望每个元素都有一个alloc,因为这样内存效率很低,所以计划编写一个类来重写[]运算符,并根据索引选择适当的元素。是不是已经有一个像样的班级可以这样做了,还是我最好自己滚?

    据我所知 googling ,一个32位的windows进程理论上应该能够处理高达2GB的地址。现在假设我已经安装了2GB,并且各种其他进程和服务占用了大约400MB,那么您认为我的程序可以合理地从堆中获得多少可用内存?

    我现在使用Visual C++的各种味道。

    编辑 根据波塔的帖子,我试过 STD::德克 ,在VS2008上使用以下测试;

    #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秒。deque的大小调整最初占用了950mb,然后慢慢开始回落。15分钟后,dequetest()完成,仅为进程显示6MB内存,这可能与运行时间有关。我也试着用各种推送选项填充deque,但是性能太差了,我不得不提前退出。我可以提供一个比defualt更好的分配器来获得更好的响应,但是从表面上看deque不是这个工作的类。注意,这也可能与deque的ms-vs2008实现有关,因为这个类中似乎有很多在性能方面非常依赖于实现。

    我想是时候写我自己的大数组类了。

    第二次编辑: 使用以下方法分配较小的数量,立即产生1875gb;

    #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)随机元素访问,基于每个块的固定元素数,这是我需要的。感谢大家的反馈!

    4 回复  |  直到 14 年前
        1
  •  11
  •   Peter Alexander    14 年前

    你试过用 std::deque ?不像 std::vector ,它使用一个巨大的堆分配, deque 通常以小块形式分配,但仍然通过 operator[] .

        2
  •  5
  •   Community PPrice    7 年前

    这个数组到底有多稀疏?如果其中有大量空(未使用)空间,则可能需要采取其他方法。这个 answer to this question 建议使用stl映射。

    如果它不是稀疏的(如注释中提到的),那么有一件事您可以考虑,因为您是在windows上运行的 memory-mapped file . 虽然您的操作系统可能是32位的,但您的文件系统不是。当然,这意味着交换会继续进行,这可能会比你真的把所有该死的东西放到ram中要慢得多。

    另外,你真的应该考虑把系统的ram提高到最大值(我相信32位windows上是3gb),看看这是否能帮你解决问题。你只需要花100美元,而且你花在工时上的钱还不止这些,只是担心这个。

        3
  •  3
  •   tloach    14 年前

    从程序的角度来看,无论系统中发生了什么,启动时始终有2GB可用。我不相信windows提供了一种检测内存是否被调出磁盘的方法。就数据结构而言,听起来像是在描述类似于在stl中如何实现deque的东西。

        4
  •  1
  •   Drew Hall    14 年前

    STD:DeQue:确实是你所描述的,但通常在操作系统页面大小的粒度(即,它分配的块通常为4 KB)。

    如果您对deque的默认性能不满意,那么您可以编写一个自定义分配器来获取更大的块——也就是说,一次获得1 MB或更多。

    正如其他人所说,进程的虚拟地址空间完全独立于所有其他进程,因此无论系统中发生什么,都可以寻址2GB。操作系统将根据需要将内存页交换到磁盘或从磁盘交换内存页,以适应安装内存量和所有争用内存的进程的限制。这将发生在4kb的页面大小,与块的大小无关。