Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выделение памяти разом, Есть ли смысл 
V
    Опции темы
OpenMan
Дата 5.8.2010, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 19.4.2009

Репутация: 1
Всего: 1



Доброго времени суток.
Не знаю даже как правильно вопрос-то задать, мне собственно нужна скорее Ваша консультация.
Итак, есть программа, которая при старте что-то там читает с файлов,а потом обработанные данные записывает в массив.

Цикл собственно такой: для каждого объекта (взятого при чтении с файла) вычисляется некий массив чисел, затем из этого массива чисел выбрасываются некоторые элементы и массив делается концентрированным. Затем этот массив сохраняется (в оперативке).

Что мы имеем: 
* большой набор массивов разной длинны. (в сумме примерно 3Гб (4Гб это предел вообще и 3,15 по-мойму для Виндовс))

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

Теперь собственно вопрос.

Если самому выделять большие куски памяти скажем в среднем на 1000 массивов (берется средний размер), и самому уже делить данные между массивами (моими), будет ли какая-то от этого польза?
Как было сказано данные должны занимать практически всю Оперативку, я же хочу, чтобы не было засерания кучи. Другими словами можно на бруске длинной 5 метров расположить 3 бруска по одному метру так, чтобы между ними не осталось места для 4-го бруска, т.е КПД равен 60%. Собственно я и хочу выделять память сплошными блоками. Даст ли мне что это что-нибудь?
И вообще мне бы было очень выгодно если бы часть памяти сразу можно было бы зарезервироваться под мои массивы так, чтобы маалок её для других целей не юзал.

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

Дайте консультацию по правильному распределению памяти.
PM MAIL   Вверх
djamshud
Дата 5.8.2010, 16:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



OpenMan, вы немного путаете физическую и виртуальную память. Но в целом - да, чем чаще выделять, удалять, перемещать данные, тем сильнее в конечном счете единые куски виртуальной памяти процесса будет фрагментирована физически. Поэтому смысл выделить сразу побольше есть.

>4Гб это предел вообще и 3,15 по-мойму для Виндовс

В виндовс предел 4гига минус память видеокарты (и может быть чего-нибудь еще), они в едином адресном пространстве работают почему-то. Проблемы нет на x86_64.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
OpenMan
Дата 5.8.2010, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 19.4.2009

Репутация: 1
Всего: 1



А до какого предела "больше" есть смысл выделять, Можно ли сразу выделить одну отдельную виртуальную страницу памяти (1 большой массив в 1 странице)?
Было как-то, что программа не смогла выделить 10 массивов по 200 метров, помойму на 4-м массиве программа вылетала с ошибкой, хотя таск менеждер говорил, что место ещё много. А вот меньшими кусками выделять получалось.
PM MAIL   Вверх
bsa
Дата 5.8.2010, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(OpenMan @  5.8.2010,  18:00 Найти цитируемый пост)
Можно ли сразу выделить одну отдельную виртуальную страницу памяти (1 большой массив в 1 странице)
Если мне память не изменяет, размер страницы памяти равен 4 килобайтам (4096 байт). Ты уверен, что тебе будет достаточно?  smile 

В принципе, подобные задачи надо решать через "виртуальную память" организованную на уровне твоей программы. Т.е. у тебя объект "массив" будет более умной единицей, чем кусок памяти, и по определенному сигналу будет полностью (за исключением данных, необходимых для загрузки) выгружаться из памяти в файл. А при первой попытке доступа загружаться обратно. Таким образом, ты можешь неиспользуемые массивы выгружать из памяти, не задумываясь о том, когда их надо загружать - загрузятся сами.
Если же ты используешь все массивы одновременно (интересно, зачем?), то тут придется просто менять платформу на 64-х битную и увеличивать объем памяти.
PM   Вверх
icecrashldr
Дата 5.8.2010, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Developer
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 5.7.2010

Репутация: нет
Всего: нет



на 32 двух разрядной машине больше двух гиг, а в реале меньше будет чем два гига, выделить не получится.
OpenMan
Если вы хотите использовать большую память, как масив, рекомендую делать MapView и можно будет сделать селектор. Скорость будет хорошой, памяти жрать много не будет.

PM MAIL WWW   Вверх
borisbn
Дата 5.8.2010, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(bsa @  5.8.2010,  17:21 Найти цитируемый пост)
по определенному сигналу будет полностью (за исключением данных, необходимых для загрузки) выгружаться из памяти в файл. А при первой попытке доступа загружаться обратно

это же swap-файл. Он уже реализован ОС ( windows точно, linux - не знаю ). Зачем его переписывать ?

Цитата(djamshud @  5.8.2010,  16:44 Найти цитируемый пост)
Но в целом - да, чем чаще выделять, удалять, перемещать данные, тем сильнее в конечном счете единые куски виртуальной памяти процесса будет фрагментирована физически. Поэтому смысл выделить сразу побольше есть.

В принципе хороший менеджер памяти должен сам делать дефрагментацию. Я не знаю на чём пишет ТС, но если на Builder'е, то там менеджер вообще её не делает, а Visual по-моему делает, но как-то криво ( во всяком случае я не заметил его работы ), поэтому действительно есть смысл выделить сразу побольше.


Это сообщение отредактировал(а) borisbn - 5.8.2010, 18:10


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
djamshud
Дата 5.8.2010, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



OpenMan, у меня почти нет опыта программирования в виндовс, но сейчас я решаю в чем-то похожую наверное задачу в линуксе.

Что делается? Строится и естественно просчитывается имитационнаяя модель. Не важно, чего. На данном этапе используется около двух с половиной гигабайт памяти.

Как делается? Написан небольшой юзерспейсовский менеджер памяти; основная программа сначала обрабатывает входные данные, вычисляет необходимый объем памяти для рассчета и так называемые ее сегменты - то есть участки, которые в дальнейшем алгоритм последовательно обрабатывает - и настраивает менеджер. Он в свою очередь сразу берет и mmap-ит нужный кусок (как я писал - около 2.5Гб). Дальше программа запрашивает у менеджера данные под массивы и иногда отдельные структуры, а тот в свою очередь смотрит, в каком сегменте запрошена память, и отщипывает нужный кусочек программе.

В итоге, какой профит в сравнении с обыными миллионами malloc-ов: скорость выделения памяти выросла на 0-15%, скорость алгоритма - на 10-30%. Разбросы большие, потому что в основе всего естественно лежит менеджер памяти операционной системы, и даже казалось бы один виртуальный кусок памяти в действительности может быть соткан из тысяч физических.

Добавлено @ 18:53
>Если мне память не изменяет, размер страницы памяти равен 4 килобайтам (4096 байт).

Не всегда. Но лучше работать с адресами, кратными PAGE_SIZE. Выше описанный менеджер так выравнивает сегменты и большие участки внутри сегментов.

Это сообщение отредактировал(а) djamshud - 5.8.2010, 18:55


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
bsa
Дата 5.8.2010, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(borisbn @  5.8.2010,  19:08 Найти цитируемый пост)
это же swap-файл. 

На системный своп тоже есть ограничения. Примерно такие же, как на оперативку. А в случае своей реализации, они будут совершенно иные.
PM   Вверх
OpenMan
Дата 5.8.2010, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 19.4.2009

Репутация: 1
Всего: 1



спасибо всем отписавшимся. 

Программа что-то вроде базы данных, данных очень много и их природа токава, что их нереально поделить, поэтому искать каждый запрос нужно по всей базе а это значит надо все держать в оперативке.

Пишу на детище Борладна,  не я ваыбирал - приказали. Сколько юзаю я билдер столько матюкаюсь. Хотя наверное, это общая проблема для С++ (на java проблем у меня со средами не возникало, но там ведь виртуальная машина и веритификация в разу сильнее).

Не очень понял про MapView. Если можно , то поподробней, я не заком с контейнерами данный в С++, обычно мне легче самому какой-нибудь хеш написать, чем в чужом разбираться. Так что если можно просветите меня.

Насчет скорости и маалоков всяких - не критично, надо будет дождаться пока все данные загрузятся значит пользователь подождет. У программы пока 2 режима: режим индексации данных (переводит объекты в массивы) и режим использования (грузит данные и использует), так что в моем случае не нужен крутой многофуекциональный менеджер данных, так как мне нужно будет только выделять память (а отдача памяти не нужен).

PM MAIL   Вверх
icecrashldr
Дата 6.8.2010, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Developer
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 5.7.2010

Репутация: нет
Всего: нет



Все очень просто, расщипляеш свою "базу" по сто метров. Сохраняешь их в файлы(каждый файл сто метров или больше или меньше по усмотрению). К каждому файлу прицепляешь индекс. После чего делаешь такое опражения


Код

char * 
LdrMemoryFromFile( unsigned int index )
{
         HANDLE hFile;
         HANDLE hFileMap;
         char *  retPtr = NULL;

         hFile = CreateFile( , , , , ,, );
         if ( hFile == INVALID_HANDLE_VALUE ) {
                return NULL; //это случай error
         }

         hFileMap = CreateFileMapping(hFile, ,, , , , );
         if (hFileMap == NULL ) {

                 CloseHandle(hFile);
                 return NULL; //это случай error
         }

         /// FILE_MAP_ALL_ACCESS запрос на read/write к памяти
        retPtr = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, BUFFER_SIZE);

        if ( retPtr == NULL ) {
             CloseHandle(hMapFile);
             CloseHandle(hFile);
        }
        
        return retPtr;
}


После использования памяти, надо сделать unmap и закрыть handles
Код

         UnmapViewOfFile(pMemory);
         CloseHandle(hMapFile);
         CloseHandle(hFile);


Как организовать код смотри на свое усмотрение, это простой пример.

PM MAIL WWW   Вверх
asd
Дата 6.8.2010, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 25.6.2006

Репутация: нет
Всего: 1



Цитата(OpenMan @  5.8.2010,  16:34 Найти цитируемый пост)
И вообще мне бы было очень выгодно если бы часть памяти сразу можно было бы зарезервироваться под мои массивы так, чтобы маалок её для других целей не юзал.

Для винды
LPVOID WINAPI VirtualAlloc(
  __in          LPVOID lpAddress,
  __in          SIZE_T dwSize,
  __in          DWORD flAllocationType,
  __in          DWORD flProtect
);

Смотри flAllocationType, MEM_RESERVE



PM MAIL   Вверх
REZiaMIX
Дата 6.8.2010, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



Давным-давно писал свой 'менеджер памяти', расчитанный под выделение одинаковых кусочков памяти.
При старте менеджера выделялась память под n-ное количество кусочков. При нехватке изначально выделенного происходило довыделение памяти , опять же с запасом. 

В итоге:
Ситуация первая
При старте программы инициализация менеджера(выделение около 100мб под кусочки).
Выделение памяти методом менеджера памяти(назовоем mmalloc) - заняло x мс
Выделение памяти методом malloc - заняло 15х мс 
Т.е. в данной ситуации прирост просто огромный.
Ситуация вторая
Замер скорости выделения:
Код

mmem.init(); // выделение большого куска памяти
for(uint a=0;a!=большое число;++a)mmem.alloc();

и
Код

for(uint a=0;a!=большое число;++a)malloc(x);

Т.е. делаем замер скорости выделения большого куска памяти и всех мелких кусочков памяти(уже по факту просто выдача от большого)
Выигрыш в ситуации номер 2 составил ~2х, тоже очень не хило.

Также не забываем, что кроме выделения нужно иногда память и освобождать) Тут мой менеджер тоже давал нехилые приросты скорости по сравнению с обычными методами выделения.

Менеджер писался just for fun и использовался только в одном проекте(ради теста). На самом деле выделение памяти обычно далеко не самое узкое место в производительности программы. Также стоит заметить, что эффективность моего менеджера памяти росла обратно пропорционально размеру выделяемого куска памяти. Чем меньше кусок, тем больше эффективность. При выделении больших(1-10мб) кусков прирост в производительности оказался не таким огромным, но всеже существенным.

Еще плюс данного менеджера, что можно прикрутить эмуляцию свопа, на случай допустим нехватки виртуальной памяти(и такое бывает)
В авторском случае, придумать можно много чего(правда прийдется проверять эффективность), допустим как предложил icecrashldr:
Прямо в менеджер прикрутить все фичи по работе с памятью: скидывание в своп редкоиспользуемых кусков(можно ли их определить?), доступ к кускам данных по индексам, как предложил icecrashldr. При этом для основного кода вся реализация менеджера будет скрыта, менеджер будет сам решать в каких случаях и откуда брать данные.

ИМХО: такой менеджер памяти необходим или при работе с очень большими объемами данных(тут поможет авто-своппинг), или когда приложение очень активно работает с большим кол-вом маленьких кусков памяти

Это сообщение отредактировал(а) REZiaMIX - 6.8.2010, 10:46


--------------------
user posted image
PM MAIL   Вверх
xvr
Дата 12.8.2010, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Вот это:

Цитата(OpenMan @  5.8.2010,  16:34 Найти цитируемый пост)
Что мы имеем: 
* большой набор массивов разной длинны. (в сумме примерно 3Гб)


и это:

Цитата(OpenMan @  5.8.2010,  21:46 Найти цитируемый пост)
У программы пока 2 режима: режим индексации данных (переводит объекты в массивы)


не совместимо - 3Гб массивов и еще черт знает сколько Гб исходных объектов в 4Гб адресного пространства 32х битного приложения физически не поместятся.

При таких объемах напрашивается база данных (тем более что у Builder'а с этим проблем нет)

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0567 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.