Хороший класс массива C++ для контакта с большими массивами данных в быстром и памяти эффективный путь?

Следуя за предыдущим вопросом, касающимся ограничений использования "кучи", я ищу хороший стандартный класс C++ для контакта с большими массивами данных способом, которые являются и эффективной памятью и эффективной скоростью. Я выделял массив с помощью единственного malloc/HealAlloc, но после нескольких попыток с помощью различных вызовов, продолжайте ссориться с фрагментацией "кучи". Таким образом, заключение, я приехал в кроме портирования на 64 бита, состоит в том, чтобы использовать механизм, который позволяет мне иметь большой массив, охватывающий несколько меньших фрагментов памяти. Я не хочу выделение на элемент, поскольку это - очень неэффективная память, таким образом, план состоит в том, чтобы записать класс, который переопределяет [] оператор, и выберите соответствующий элемент на основе индекса. Уже существует ли достойный класс там, чтобы сделать это, или действительно ли я - более обеспеченная прокрутка мое собственное?

От моего понимания и некоторого поиска с помощью Google, процесс Windows на 32 бита должен теоретически смочь адрес до 2 ГБ. Теперь принятие мне установили 2 ГБ, и различные другие процессы и услуги, составляет hogging приблизительно 400 МБ, сколько применимой памяти Вы думаете, что моя программа может обоснованно ожидать добираться от "кучи"?

Я в настоящее время использую различные ароматы Visual C++.

Редактирование Согласно сообщению Poita, я попробовал станд.:: двухсторонняя очередь, с помощью следующего теста на VS2008;

#include 
using namespace std;
struct V    
{
    double  data[11];
};

struct T
{
    long    data[8];    
};


void    dequeTest()
{
    deque VQ;
    deque TQ;

    V defV;
    T defT;

    VQ.resize(4000000,defV);
    TQ.resize(8000000,defT);
}

Общая память для вышеупомянутых данных выходит на уровне 608 МБ, был я для использования прямого malloc или HeapAlloc, и занимает <1 секунду. Двухсторонняя очередь изменяет размер, взял 950 МБ первоначально и затем медленно начинал ронять. 15 минут спустя, dequeTest () законченный, с помощью всего 6 МБ показа памяти для процесса, который, вероятно, больше относился ко времени выполнения. Я также пытался заполнить двухстороннюю очередь с помощью различных опций нажатия, но производительность была так плоха, я должен был вспыхнуть рано. Я мог возможно обеспечить лучшее средство выделения, чем defualt для получения намного лучшего ответа, но на первый взгляд двухсторонняя очередь не является классом для этого задания. Обратите внимание, что это могло также коснуться реализации VS2008 MS двухсторонней очереди, поскольку, кажется, существует много в этом классе, который является очень иждивенцем реализации когда дело доходит до производительности.

Время для записи моего собственного большого класса массива я считаю.

Второе Редактирование: Выделение меньших сумм сразу привело к 1.875 ГБ с помощью следующего;

#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 и различные комментарии после нее, не потому что я буду использовать класс двухсторонней очереди непосредственно, но больше для массива как дека понятия карт в комментариях, которые следовали. Это должно быть просто для реализации с O (1) случайный доступ элемента, на основе постоянного числа элементов на блок, который является тем, в чем я нуждаюсь. Благодаря всем для обратной связи!

8
задан Community 23 May 2017 в 12:02
поделиться

4 ответа

Вы пробовали использовать std :: deque ? В отличие от std :: vector , в котором используется одно огромное выделение кучи, deque обычно выделяется небольшими порциями, но по-прежнему обеспечивает амортизированное постоянное временное индексирование с помощью оператора [] .

11
ответ дан 5 December 2019 в 08:23
поделиться

Насколько разрежен этот массив? Если в нем много пустого (неиспользуемого) места, вы можете выбрать другой подход. Ответ на этот вопрос предлагает карту stl.

Если он не редкий (как упоминалось в комментариях), вы можете изучить одну вещь, поскольку вы работаете в Windows, - это использование файла с отображением памяти . Хотя ваша ОС может быть 32-разрядной, файловая система - нет. Это, конечно, означает, что свопинг будет происходить, что, вероятно, будет немного медленнее, чем если бы вы действительно могли поместить всю эту чертову вещь в ОЗУ.

Кроме того, вам действительно следует подумать о том, чтобы увеличить объем оперативной памяти системы до максимума (я полагаю, 3 ГБ в 32-битной Windows), чтобы посмотреть, решит ли это проблему для вас. Это должно стоить вам всего около 100 долларов, и вы тратите гораздо больше человеко-часов, просто беспокоясь об этом.

5
ответ дан 5 December 2019 в 08:23
поделиться

С точки зрения Если посмотреть на вашу программу, у вас всегда будет доступно 2 ГБ при запуске, независимо от того, что еще происходит в системе. Я не верю, что Windows предоставляет способ определить, выгружается ли у вас память на диск или нет. Что касается ваших структур данных, похоже, вы описываете нечто похожее на то, как двухсторонняя очередь реализована в STL.

3
ответ дан 5 December 2019 в 08:23
поделиться

std :: deque делает именно то, что вы описываете, но обычно с детализацией размера страницы ОС (то есть выделяемые им фрагменты обычно составляют 4 КБ).

Если вас не устраивает производительность deque по умолчанию, вы можете написать собственный распределитель, который захватывает большие фрагменты, то есть получает 1 МБ или более за раз.

Как говорили другие, виртуальное адресное пространство вашего процесса полностью независимо от всех других процессов, поэтому вы можете адресовать 2 ГБ независимо от того, что еще происходит в вашей системе. ОС будет переставлять страницы вашей памяти на диск или с диска по мере необходимости, чтобы соответствовать ограничениям объема установленной памяти и всем процессам, которые за нее борются. Это произойдет при размере страницы 4 КБ, независимо от размера ваших фрагментов.

1
ответ дан 5 December 2019 в 08:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: