Очень большой массив в куче (Visual C++)

Я надеюсь, что кто-нибудь может мне помочь, я пытаюсь создать массив int[400000000] (400 миллионов) в своем приложении с помощью Visual C++ 2010, но он генерирует ошибку переполнения. Тот же код работает в Linux с g++. Мне это нужно, потому что я работаю с большими матрицами. Заранее спасибо.


person user445106    schedule 11.09.2010    source источник
comment
вы пытаетесь создать его динамически?   -  person cripox    schedule 11.09.2010
comment
Возможно, если вы расскажете об основной проблеме, которую пытаетесь решить, мы сможем быть более полезными.   -  person Eldad Mor    schedule 11.09.2010
comment
В некоторых системах существует ограничение на размер кадра стека. Вы можете столкнуться с этим. Используйте std::vector‹›, чтобы увидеть, решает ли это проблему (иначе у вас просто не хватает памяти.   -  person Martin York    schedule 11.09.2010
comment
См.: stackoverflow.com/questions/216259/   -  person Martin York    schedule 11.09.2010


Ответы (6)


Если вы используете 32-разрядное приложение, то по умолчанию у вас есть только 2 ГБ пользовательского адресного пространства. 400 миллионов целых чисел составляют около 1,5 ГБ. Скорее всего, у вас нет такого большого непрерывного адресного пространства. Можно заставить 32-разрядные окна выделять 3 ГБ пользовательского адресного пространства для каждого процесса, но это может быть временным промежутком в вашей ситуации.

Если вы можете перейти на 64-битную архитектуру, это не должно быть проблемой; в противном случае вам следует найти способ хранения ваших матричных данных таким образом, чтобы не требовался единый блок непрерывного хранилища, например, сохранение его в кусках.

person CB Bailey    schedule 11.09.2010
comment
+1, ага. 650 МБ — это все, что вы можете ожидать. Хранение матрицы в более интеллектуальной структуре данных также очень важно для скорости. - person Hans Passant; 11.09.2010
comment
Для скорости это зависит от ваших шаблонов доступа. Для прямого линейного прохождения данных разница между операционной системой, выгружающей старые страницы, и стратегией ручного кэширования может быть незначительной. Если (например!) вы выполняете умножение матриц на матрицах 20000 x 20000, очень сложно придумать быструю стратегию, так как вам нужно комбинировать числа из всех областей матриц во всех комбинациях. - person CB Bailey; 11.09.2010
comment
@Charles: Не это сложно. Просто нужно использовать блокировку :) - person jalf; 11.09.2010
comment
@jalf: Просто чтобы я понял, что вы подразумеваете под «блокировкой» в этом контексте? - person CB Bailey; 11.09.2010
comment
@Charles: netlib.org/utk/papers/autoblock/node2.html например - в основном разделите матрицу на более мелкие блоки (размер которых соответствует размеру кеша или основной памяти) и выполните как можно больше работы над одним блоком, прежде чем заменить его на следующий. Распространенный способ улучшить поведение кэша в таких алгоритмах, как умножение матриц. - person jalf; 12.09.2010
comment
@jalf: я должен признать, что у меня никогда не было необходимости реализовывать блочный алгоритм для умножения матриц, но у меня сложилось впечатление, что вам нужно очень быстро объединить (т.е. добавить результаты) блоки, сгенерированные путем умножения подблоков со всего диапазона адресов, поэтому для меня не очевидно, что легко получить значительный прирост скорости. - person CB Bailey; 12.09.2010
comment
@Charles: я думаю, что мы отклоняемся от темы здесь, но это значительно сокращает количество промахов кеша (или ошибок страниц или чего-то еще, чего вы пытаетесь избежать). Предполагая, конечно, что это то, что ограничивает вашу производительность, это очень полезное семейство оптимизаций. Будучи студентом, я использовал его варианты в нескольких исследовательских проектах, и прирост скорости может быть значительным, но он сильно зависит от аппаратного обеспечения, размера вашего ввода и так далее. - person jalf; 12.09.2010

Я думаю, что вам нужен алгоритм «разделяй и властвуй». Не место в памяти.

person Elroy    schedule 11.09.2010
comment
это не полезно - person eddyq; 02.09.2017

Я не уверен, что в вашем случае лучше использовать STXXL.

person Klaim    schedule 11.09.2010

Возможно, в вашем приложении используются разреженные матрицы. Эта концепция используется при работе с большими матрицами, в которых много нулевых элементов, что может иметь место во многих приложениях.

И кстати, вы ничего не выигрываете, храня такое огромное количество данных в куче. Учтите, что кэш вашего процессора может быть 12 МБ! По крайней мере, используйте какой-нибудь интеллектуальный механизм динамического распределения памяти.

person Danvil    schedule 11.09.2010

Действительно ли нужно выделять весь массив? вы действительно используете весь массив? Это массив с большим количеством 0? если это так, то можно объяснить тот факт, что он лучше работает в linux.

В этом случае использование разреженного массива может быть более подходящим. Использование существующей реализации разреженного массива уменьшит объем памяти и, возможно, позволит ускорить вычисления.

person Community    schedule 11.09.2010

Я только что нашел очень простое решение, но я не знаю, целесообразно ли это

int tab[400000000]={0};//global array

int main(array<System::String ^> ^args)
{
std::cout<<tab[399999999]<<std::endl;//ok

/*
int* tab=new int[400000000];//doesn't work
...
delete[] tab;
*/
    return 0;
}
person user445106    schedule 14.09.2010
comment
Ваше решение здесь состоит в том, чтобы захватить адресное пространство очень рано. Не полагайтесь на то, что это работает для такого большого блока на 32 битах, это будет хрупким для окружающей среды. - person morechilli; 14.09.2010