![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| OpenMan |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 19.4.2009 Репутация: 1 Всего: 1 |
Доброго времени суток.
Не знаю даже как правильно вопрос-то задать, мне собственно нужна скорее Ваша консультация. Итак, есть программа, которая при старте что-то там читает с файлов,а потом обработанные данные записывает в массив. Цикл собственно такой: для каждого объекта (взятого при чтении с файла) вычисляется некий массив чисел, затем из этого массива чисел выбрасываются некоторые элементы и массив делается концентрированным. Затем этот массив сохраняется (в оперативке). Что мы имеем: * большой набор массивов разной длинны. (в сумме примерно 3Гб (4Гб это предел вообще и 3,15 по-мойму для Виндовс)) Велика вероятность, что ни один из этих массивов не будет удален, т.е. все данные имеют срок жизни равный жизни самого приложения. Теперь собственно вопрос. Если самому выделять большие куски памяти скажем в среднем на 1000 массивов (берется средний размер), и самому уже делить данные между массивами (моими), будет ли какая-то от этого польза? Как было сказано данные должны занимать практически всю Оперативку, я же хочу, чтобы не было засерания кучи. Другими словами можно на бруске длинной 5 метров расположить 3 бруска по одному метру так, чтобы между ними не осталось места для 4-го бруска, т.е КПД равен 60%. Собственно я и хочу выделять память сплошными блоками. Даст ли мне что это что-нибудь? И вообще мне бы было очень выгодно если бы часть памяти сразу можно было бы зарезервироваться под мои массивы так, чтобы маалок её для других целей не юзал. С другой стороны может получиться так, что в куче не будет нужного количества сплошных кусков памяти того размера которого я запрашиваю, но будет суммарный нужный мне объем. И получиться так, что программа будет вылетать с ошибкой. Дайте консультацию по правильному распределению памяти. |
|||
|
||||
| djamshud |
|
|||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 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 |
|||
|
||||
| OpenMan |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 19.4.2009 Репутация: 1 Всего: 1 |
А до какого предела "больше" есть смысл выделять, Можно ли сразу выделить одну отдельную виртуальную страницу памяти (1 большой массив в 1 странице)?
Было как-то, что программа не смогла выделить 10 массивов по 200 метров, помойму на 4-м массиве программа вылетала с ошибкой, хотя таск менеждер говорил, что место ещё много. А вот меньшими кусками выделять получалось. |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
В принципе, подобные задачи надо решать через "виртуальную память" организованную на уровне твоей программы. Т.е. у тебя объект "массив" будет более умной единицей, чем кусок памяти, и по определенному сигналу будет полностью (за исключением данных, необходимых для загрузки) выгружаться из памяти в файл. А при первой попытке доступа загружаться обратно. Таким образом, ты можешь неиспользуемые массивы выгружать из памяти, не задумываясь о том, когда их надо загружать - загрузятся сами. Если же ты используешь все массивы одновременно (интересно, зачем?), то тут придется просто менять платформу на 64-х битную и увеличивать объем памяти. |
|||
|
||||
| icecrashldr |
|
|||
![]() Developer ![]() Профиль Группа: Участник Сообщений: 122 Регистрация: 5.7.2010 Репутация: нет Всего: нет |
на 32 двух разрядной машине больше двух гиг, а в реале меньше будет чем два гига, выделить не получится.
OpenMan Если вы хотите использовать большую память, как масив, рекомендую делать MapView и можно будет сделать селектор. Скорость будет хорошой, памяти жрать много не будет. |
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
это же swap-файл. Он уже реализован ОС ( windows точно, linux - не знаю ). Зачем его переписывать ? В принципе хороший менеджер памяти должен сам делать дефрагментацию. Я не знаю на чём пишет ТС, но если на Builder'е, то там менеджер вообще её не делает, а Visual по-моему делает, но как-то криво ( во всяком случае я не заметил его работы ), поэтому действительно есть смысл выделить сразу побольше. Это сообщение отредактировал(а) borisbn - 5.8.2010, 18:10 -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| djamshud |
|
|||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 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 |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
На системный своп тоже есть ограничения. Примерно такие же, как на оперативку. А в случае своей реализации, они будут совершенно иные. |
|||
|
||||
| OpenMan |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 19.4.2009 Репутация: 1 Всего: 1 |
спасибо всем отписавшимся.
Программа что-то вроде базы данных, данных очень много и их природа токава, что их нереально поделить, поэтому искать каждый запрос нужно по всей базе а это значит надо все держать в оперативке. Пишу на детище Борладна, не я ваыбирал - приказали. Сколько юзаю я билдер столько матюкаюсь. Хотя наверное, это общая проблема для С++ (на java проблем у меня со средами не возникало, но там ведь виртуальная машина и веритификация в разу сильнее). Не очень понял про MapView. Если можно , то поподробней, я не заком с контейнерами данный в С++, обычно мне легче самому какой-нибудь хеш написать, чем в чужом разбираться. Так что если можно просветите меня. Насчет скорости и маалоков всяких - не критично, надо будет дождаться пока все данные загрузятся значит пользователь подождет. У программы пока 2 режима: режим индексации данных (переводит объекты в массивы) и режим использования (грузит данные и использует), так что в моем случае не нужен крутой многофуекциональный менеджер данных, так как мне нужно будет только выделять память (а отдача памяти не нужен). |
|||
|
||||
| icecrashldr |
|
||||
![]() Developer ![]() Профиль Группа: Участник Сообщений: 122 Регистрация: 5.7.2010 Репутация: нет Всего: нет |
Все очень просто, расщипляеш свою "базу" по сто метров. Сохраняешь их в файлы(каждый файл сто метров или больше или меньше по усмотрению). К каждому файлу прицепляешь индекс. После чего делаешь такое опражения
После использования памяти, надо сделать unmap и закрыть handles
Как организовать код смотри на свое усмотрение, это простой пример. |
||||
|
|||||
| asd |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 25.6.2006 Репутация: нет Всего: 1 |
Для винды LPVOID WINAPI VirtualAlloc( __in LPVOID lpAddress, __in SIZE_T dwSize, __in DWORD flAllocationType, __in DWORD flProtect ); Смотри flAllocationType, MEM_RESERVE |
|||
|
||||
| REZiaMIX |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 346 Регистрация: 3.11.2007 Репутация: нет Всего: 4 |
Давным-давно писал свой 'менеджер памяти', расчитанный под выделение одинаковых кусочков памяти.
При старте менеджера выделялась память под n-ное количество кусочков. При нехватке изначально выделенного происходило довыделение памяти , опять же с запасом. В итоге: Ситуация первая При старте программы инициализация менеджера(выделение около 100мб под кусочки). Выделение памяти методом менеджера памяти(назовоем mmalloc) - заняло x мс Выделение памяти методом malloc - заняло 15х мс Т.е. в данной ситуации прирост просто огромный. Ситуация вторая Замер скорости выделения:
и
Т.е. делаем замер скорости выделения большого куска памяти и всех мелких кусочков памяти(уже по факту просто выдача от большого) Выигрыш в ситуации номер 2 составил ~2х, тоже очень не хило. Также не забываем, что кроме выделения нужно иногда память и освобождать) Тут мой менеджер тоже давал нехилые приросты скорости по сравнению с обычными методами выделения. Менеджер писался just for fun и использовался только в одном проекте(ради теста). На самом деле выделение памяти обычно далеко не самое узкое место в производительности программы. Также стоит заметить, что эффективность моего менеджера памяти росла обратно пропорционально размеру выделяемого куска памяти. Чем меньше кусок, тем больше эффективность. При выделении больших(1-10мб) кусков прирост в производительности оказался не таким огромным, но всеже существенным. Еще плюс данного менеджера, что можно прикрутить эмуляцию свопа, на случай допустим нехватки виртуальной памяти(и такое бывает) В авторском случае, придумать можно много чего(правда прийдется проверять эффективность), допустим как предложил icecrashldr: Прямо в менеджер прикрутить все фичи по работе с памятью: скидывание в своп редкоиспользуемых кусков(можно ли их определить?), доступ к кускам данных по индексам, как предложил icecrashldr. При этом для основного кода вся реализация менеджера будет скрыта, менеджер будет сам решать в каких случаях и откуда брать данные. ИМХО: такой менеджер памяти необходим или при работе с очень большими объемами данных(тут поможет авто-своппинг), или когда приложение очень активно работает с большим кол-вом маленьких кусков памяти Это сообщение отредактировал(а) REZiaMIX - 6.8.2010, 10:46 -------------------- ![]() |
||||
|
|||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Вот это:
и это:
не совместимо - 3Гб массивов и еще черт знает сколько Гб исходных объектов в 4Гб адресного пространства 32х битного приложения физически не поместятся. При таких объемах напрашивается база данных (тем более что у Builder'а с этим проблем нет) |
||||
|
|||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |