|
|
|
Расположение в виртуальной памяти буфера, возвращаемого MapViewOfFile
|
|||
|---|---|---|---|
|
#18+
Я использую memory-mapped файлы. Отображаю их содержимое в пямять используя MapViewOfFile. Содержимое отображается в виртуальное адресное пространсво процесса. Когда моя программа работает, мне нужно мапировать и размапировать последовательно много файлов. Если я мапирую файл 300 мб, выделяю память с помощью оператора new, размапирую файл и опять мапирую другой файл размером 600 мб, он не будет смапирован в то же место, куда отображался первый файл, т.к. адресное пространство фрагментировано - после свободных 300 мб идет участок памяти, занятый при вызове new. У процесса в 32-разрядной Windows есть ограничение в 2gb виртуального адресного пространства для операций мапирования файлов, выделения памяти. Поэтому после некоторого времени работы, после того как несколько файлов были смаппированы и размаппированы, в виртуальном адресном пространстве не остается непрерывного куска памяти для мапирования очередного файла - адресное пространство фрагментировано. Я считаю, что было бы эффективно использовать для маппирования файлов второй из двух гигабайт доступного адресного пространства. А первый гигабайт тспользовать для операций new и malloc. Поскольку я всегда мапирую в каждый момент времени один файл, я никогда не получу фрагментированного адресного пространства. Возможно ли настроить MapViewOfFile так, чтобы оно выделяло память всегда во втором гигабайте адресного пространства, а первый использовался бы new и malloc? Или просто в начале работы программы выделить буфер размером в гиг и мапировать файлы только в него? Возможно ли такое? Может это решается как-то по-другому? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.11.2007, 10:16:54 |
|
||
|
Расположение в виртуальной памяти буфера, возвращаемого MapViewOfFile
|
|||
|---|---|---|---|
|
#18+
Serge N wrote: > фрагментированного адресного пространства. Возможно ли настроить > MapViewOfFile так, чтобы оно выделяло память всегда во втором гигабайте > адресного пространства, а первый использовался бы new и malloc? Или Для этого есть MapViewOfFileEx. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.11.2007, 11:31:06 |
|
||
|
Расположение в виртуальной памяти буфера, возвращаемого MapViewOfFile
|
|||
|---|---|---|---|
|
#18+
teras Serge N wrote: > фрагментированного адресного пространства. Возможно ли настроить > MapViewOfFile так, чтобы оно выделяло память всегда во втором гигабайте > адресного пространства, а первый использовался бы new и malloc? Или Для этого есть MapViewOfFileEx. Posted via ActualForum NNTP Server 1.4 А как определить значение для параметра lpvBaseAddress, чтобы это был адрес начала второго гигабайта? Если использовать 1024*1024*1024=1 073 741 824 - это правильно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.11.2007, 16:04:05 |
|
||
|
Расположение в виртуальной памяти буфера, возвращаемого MapViewOfFile
|
|||
|---|---|---|---|
|
#18+
Serge N wrote: > > А как определить значение для параметра lpvBaseAddress, чтобы это был > адрес начала второго гигабайта? > Если использовать 1024*1024*1024=1 073 741 824 - это правильно? Вполне. Только не забудьте, что "While it is possible to specify an address that is safe now (not used by the operating system), there is no guarantee that the address will remain safe over time." - придется проверять на совместимость с будущими версиями. Если вы можете вычислить максимальный размер для отражаемых файлов, то можно просто резервировать память при помощи VirtualAlloc(NULL, MEM_RESERVE), перед тем, как мапировать файл - освобождать ее и использовать этот адрес для мапирования, при выгрузке - резервировать опять: VirtualAlloc(ADDR, MEM_RESERVE). Кроме того, я бы еще попробовал сделать VirtualAlloc(NULL, MEM_RESERVE) и MapViewOfFileEx по этому адресу - может уживуться вместе. Из документации следует только то, что нельзя делать наоборот. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.11.2007, 17:19:58 |
|
||
|
Расположение в виртуальной памяти буфера, возвращаемого MapViewOfFile
|
|||
|---|---|---|---|
|
#18+
terasЕсли вы можете вычислить максимальный размер для отражаемых файлов, то можно просто резервировать память при помощи VirtualAlloc(NULL, MEM_RESERVE), перед тем, как мапировать файл - освобождать ее и использовать этот адрес для мапирования, при выгрузке - резервировать опять: VirtualAlloc(ADDR, MEM_RESERVE). Этот вариант имеет слабое место - в моменты времени, когда файл еще или уже не смаппирован, а память еще не зарезервирована VirtualAlloc или уже разблокирована, в каком-то из потоков приложения может вызваться malloc или new, память будет занята и ее не удастся использовать. terasКроме того, я бы еще попробовал сделать VirtualAlloc(NULL, MEM_RESERVE) и MapViewOfFileEx по этому адресу - может уживуться вместе. Из документации следует только то, что нельзя делать наоборот. Posted via ActualForum NNTP Server 1.4 В статье на странице http://www.frolov-lib.ru/books/bsp/v27/ch1.htm сказано: Заметим, что функция MapViewOfFileEx сама выполняет резервирование адресов, поэтому вы не должны передавать ей адрес области памяти, полученный от функции VirtualAlloc. Я проверил - действительно, если память зарезервирована VirtualAlloc, MapViewOfFileEx возвращает ошибку. Получается что ни тот ни другой вариант не проходит. Первый очень хрупок и работает не всегда. Второй - не работает в принципе. Может есть все-таки какие-то действенные способы решения этой проблемы? Работают же как-то программы-просмотрщики dvd открывая подряд много больших файлов. Наверняка они используют мапирование в память. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.11.2007, 16:52:34 |
|
||
|
Расположение в виртуальной памяти буфера, возвращаемого MapViewOfFile
|
|||
|---|---|---|---|
|
#18+
Serge N wrote: > Получается что ни тот ни другой вариант не проходит. Первый очень хрупок > и работает не всегда. Вначале о мультипоточности речи не было. Конечно не будет работать. Конечно, при желании, можно подменить функции выделения памяти - будет работать всегда. ;-) > все-таки какие-то действенные способы решения этой проблемы? Работают же > как-то программы-просмотрщики dvd открывая подряд много больших файлов. > Наверняка они используют мапирование в память. Не обязательно. Думаю, там можно и без мапирования обойтись. Доступ явно последовательный. Открыл файл с FILE_FLAG_NO_BUFFERING + FILE_FLAG_OVERLAPPED, используешь упреждающее чтение и все. По скорости - чуть медленнее (если медленнее) чем мапирование. Может так: просканировать память при помощи VirtualQuery, найти самый большой кусок, поделить его на две части (например - отступить полгига или порезать пополам), первую оставить как есть, под обычное выделение, вторая - под мапирование? Можно еще поиграться с адресным пространством, при попадании в разные гигабайты (на случай 3G пространства программы). А при выделение памяти malloc-ом - контролировать адреса на превышение зарезервированного пространства и просить сообщить в техподдержку для изменения констант или учитывать их при следующем запуске. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.11.2007, 23:50:53 |
|
||
|
Расположение в виртуальной памяти буфера, возвращаемого MapViewOfFile
|
|||
|---|---|---|---|
|
#18+
teras Не обязательно. Думаю, там можно и без мапирования обойтись. Доступ явно последовательный. Открыл файл с FILE_FLAG_NO_BUFFERING + FILE_FLAG_OVERLAPPED, используешь упреждающее чтение и все. По скорости - чуть медленнее (если медленнее) чем мапирование. доступ не последовательный даже при просмотре DVD, т.к можно отматывать фильм назад. в моем случае доступ вообще случайный. в этом случае чтение из файла имеет смысл? terasМожет так: просканировать память при помощи VirtualQuery, найти самый большой кусок, поделить его на две части (например - отступить полгига или порезать пополам), первую оставить как есть, под обычное выделение, вторая - под мапирование? Можно еще поиграться с адресным пространством, при попадании в разные гигабайты (на случай 3G пространства программы). А при выделение памяти malloc-ом - контролировать адреса на превышение зарезервированного пространства и просить сообщить в техподдержку для изменения констант или учитывать их при следующем запуске. Posted via ActualForum NNTP Server 1.4 найти большие куски памяти не проблема - в самом начале работы программы они есть 100%. вопрос именно в том, как не дать malloc и new размещаться в куске, который используют файлы для мапирования (учитывая многопоточность)? фраза "просить сообщить в техподдержку для изменения констант или учитывать их при следующем запуске" мне не понятна. кто должен в какую техподдержку обращаться и о каких константах идет речь? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2007, 00:06:21 |
|
||
|
Расположение в виртуальной памяти буфера, возвращаемого MapViewOfFile
|
|||
|---|---|---|---|
|
#18+
Serge N wrote: > > доступ не последовательный даже при просмотре DVD, т.к можно отматывать > фильм назад. Ну и что? В файле можно и позиционироваться. Главное, что последовательный доступ явное превалирует над случайным. > в моем случае доступ вообще случайный. > в этом случае чтение из файла имеет смысл? По желанию. FILE_FLAG_NO_BUFFERING - прямое чтение сектора в указанную область памяти, минуя системный кеш. То есть, зачитать файл одyим приемом и замапировать его в память - будут работать одинаково по времени (ну или различие будет минимальным). Если же читать файл фрагментами, то будут потери времени на переключении контекста в WaitForSingleObject при ожидании завершения чтения. > > найти большие куски памяти не проблема - в самом начале работы программы > они есть 100%. > вопрос именно в том, как не дать malloc и new размещаться в куске, > который используют файлы для мапирования (учитывая многопоточность)? Проблема в том, что области для мапирования и для хипа - примыкают друг к другу. Поэтому, если мапируется только один файл за раз, я бы, пожалуй, сделал динамический поиск пространства для (подразумевается, что все потоки в программе создаются предварительно). Выравнивая область для мапирования в зависимости от размера файла на наибольшему доступному адресу из первых 2 или 3 гиг свободной памяти в программе. Дело с том, что поведение остальных областей памяти достаточно предсказуемо - хип растет вверх, стек уже зарезервирован. То есть применяется подход - оказаться как можно дальше (выше) от адресов хипа. Гарантий тут конечно никаких нет. Только предположения, что все будет работать. Если мапирование по каким-то причинам не прошло, можно вернуться к автоматической схеме (MapViewOfFile). > фраза "просить сообщить в техподдержку для изменения констант или > учитывать их при следующем запуске" мне не понятна. кто должен в какую > техподдержку обращаться и о каких константах идет речь? Это в случае, если адрес для мапирования вычисляется один раз. - находим самый большой участок свободной памяти, берем пиковое собственное потребление памяти, умножаем его на два (это и будет той константой), затем, оставляем на эту константу отступаем от нижней границы свободной памяти и мапируем файлы туда. Если оказалось, что пиковое выделение спрогнозировано неправильно, то malloc вернет адрес, превышающий область мапирования. В этом случае просим пользователя передать эту информацию нам. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2007, 01:25:50 |
|
||
|
|

start [/forum/topic.php?fid=57&fpage=269&tid=2027845]: |
0ms |
get settings: |
8ms |
get forum list: |
20ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
66ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
37ms |
get tp. blocked users: |
1ms |
| others: | 191ms |
| total: | 341ms |

| 0 / 0 |
