Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Массив с Memory-Mapped file


Автор: Kronos 26.6.2005, 10:55
возможно ли это в C#

Задача. Задать большой массив скажем double[10 000 000]. При этом данные хранятся в файле в бинарном виде. Самый простой вариант считать их оттуда в буфер памяти (прямо сразу в массив). Это работает.

Но есть и другой вариант. Это должно работать на обычном С++. Создать Memory-mapped file и сделать отображение файла на адресное пространство буфера. Тогда считывание данных и их "кэширование" будет производится только по факту обращения к элементам массива.

Как мне кажется такое пройдет и в .NET (скажу честно, еще не проверял). Естественно отображение и все такое надо также осуществлять в unsafe. Но вот проблема. При выходе из блока unsafe, .NET имеет право перемещать положение объектов (и нашего массива в том числе) в адресном пространстве. Тогда как отображенное пространство должно будет оставаться на одном месте постоянно. Вроде необходима явная поддержка memory-mapped files со стороны .NET. В MSDN ничего не нашел (плохо искал?). Ведь такой эффективный механизм.

Итак. Есть ли его реализация. Если нет изначально. То можно ли осуществить теоретически (обычному программисту создать такой класс). Тут как то придется управлять сборщиком мусора (который дефрагментирует объекты и вызывает их перемещение в адресном пространстве).


Автор: mr.DUDA 26.6.2005, 12:25
Можно использовать винапишные ф-ции для работы с memory mapped file, но это долго и муторно, и нужно делать unsafe проект.

Ещё, поищи в сети информацию о Microsoft.ApplicationBlocks.MemoryMappedFile.dll, у меня сейчас нет возможности выложить саму длл-ку, т.к. она лежит на работе, а с microsoft.com можно выкачать только Enterprise Library целиком (доступ есть только зарегистрированным юзерам).

Автор: Kronos 26.6.2005, 12:51
Цитата(mr @ 26.6.2005, 09:25)
Можно использовать винапишные ф-ции для работы с memory mapped file, но это долго и муторно, и нужно делать unsafe проект


Об этом я примерно и говорил. Проблема в том, что при выходе из unsafe блока (и из блока fixed соответственно) такой массив становится неюзабельным. Его адрес мржет изменится, при этом адрес отображенной области синхронно не изменится.

Автор: mr.DUDA 26.6.2005, 16:29
Цитата(Kronos @ 26.6.2005, 12:51)
Проблема в том, что при выходе из unsafe блока (и из блока fixed соответственно) такой массив становится неюзабельным.

Так, если я правильно понял, все операции над отображаемым файлом можно выполнить в рамках unsafe блока. Если же что-то нужно вернуть (типа фрагмент массива и т.п.), можно скопировать это "что-то" в обычный массив или переменную. Где тут проблема ?

Автор: Kronos 26.6.2005, 20:12
Цитата(mr @ 26.6.2005, 13:29)
Так, если я правильно понял, все операции над отображаемым файлом можно выполнить в рамках unsafe блока. Если же что-то нужно вернуть (типа фрагмент массива и т.п.), можно скопировать это "что-то" в обычный массив или переменную. Где тут проблема ?


Конечно можно и копировать. Вопрос лишь в производительности. Хотелось бы избежать копирования скажем сотни мегабайт памяти.

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

Конечно впоследствии после явного копирования массив вероятно все равно сбросится в файл подкачки. Но все равно операция явного копирования большой области памяти выглядит лишней и занимает время. А если придется работать с кучей массивов в цикле и по логике программы всего лишь необходимо вносить изменения в пару элементов каждого массива (но каких, заранее неизвестно)?

Автор: mr.DUDA 26.6.2005, 22:22
Цитата(Kronos @ 26.6.2005, 20:12)
А если придется работать с кучей массивов в цикле и по логике программы всего лишь необходимо вносить изменения в пару элементов каждого массива (но каких, заранее неизвестно)?

Подожди. В рамках одного метода известно, какие именно ячейки массива должны быть обработаны/возвращены, правильно ? Вот их и обрабатывай в unsafe-блоке. Зачем копировать большие блоки памяти туда-сюда, если реально обработке подвергаются только избранные блоки памяти ?

Автор: Guest 27.6.2005, 08:59
Цитата(mr @ 26.6.2005, 22:22)
Подожди. В рамках одного метода известно, какие именно ячейки массива должны быть обработаны/возвращены, правильно ? Вот их и обрабатывай в unsafe-блоке. Зачем копировать большие блоки памяти туда-сюда, если реально обработке подвергаются только избранные блоки памяти ?


Ну нет. это при каждом обращении к элементу массива строить отображение и входить в unsafe? Какие интересно будут потери в производительности, тогда как именно из-за производительности все это затевалось. Да и не совсем удобно это.

Автор: mr.DUDA 27.6.2005, 09:24
Цитата
Ну нет. это при каждом обращении к элементу массива строить отображение и входить в unsafe? Какие интересно будут потери в производительности, тогда как именно из-за производительности все это затевалось. Да и не совсем удобно это.

Я не это имел ввиду. Обработка отображаемого файла может быть целиком помещена в отдельный метод, работающий в unsafe.

Вот, нашёл у себя майкрософтовский MemoryMappedFile, выкладываю.

Автор: Guest 27.6.2005, 10:32
Цитата(mr @ 27.6.2005, 09:24)
Я не это имел ввиду. Обработка отображаемого файла может быть целиком помещена в отдельный метод, работающий в unsafe.


С трудом понимаю. С массивом придется работать много и в разных частях программы. Придется все функции объявлять unsafe и вероятно возникнут сложности с использованием fixed(){} (без него вроде не обойтись). В общем не уверен.

Цитата(mr @ 27.6.2005, 09:24)
Вот, нашёл у себя майкрософтовский MemoryMappedFile, выкладываю.

Спасибо. Посмотрю.

Автор: mr.DUDA 27.6.2005, 10:39
Цитата(Guest @ 27.6.2005, 10:32)
С трудом понимаю. С массивом придется работать много и в разных частях программы. Придется все функции объявлять unsafe и вероятно возникнут сложности с использованием fixed(){} (без него вроде не обойтись). В общем не уверен.

Ну, если задача стоит таким образом, то без нескольких unsafe действительно не обойтись.

Автор: Kronos 28.6.2005, 20:32
Цитата(mr @ 27.6.2005, 06:24)
Вот, нашёл у себя майкрософтовский MemoryMappedFile, выкладываю.


Документацию на эту dll я не нашел. Даже на сайте microsoft. Все что находится - нечто левое.
Есть ли такая документация в том пакете, в котором, как ты говорил, содержалась эта dll?

Я так понимаю это библиотека .NET?

Автор: mr.DUDA 28.6.2005, 21:34
Цитата(Kronos @ 28.6.2005, 20:32)
Документацию на эту dll я не нашел. Даже на сайте microsoft. Все что находится - нечто левое.

The patterns & practices Enterprise Library is a library of application blocks designed to assist developers with common enterprise development challenges. Application blocks are a type of guidance, provided as source code that can be used "as is," extended, or modified by developers to use on enterprise development projects. Enterprise Library features new and updated versions of application blocks that were previously available as stand-alone application blocks. All Enterprise Library application blocks have been updated with a particular focus on consistency, extensibility, ease of use, and integration.

На сайте есть download всей библиотеки, судя по всему, с хелпом (т.к. занимает 8 Мб). Отдельно скачать MMF можно по ссылке:
http://download.microsoft.com/download/b/2/d/b2d215e2-63a4-428c-ad26-af3947790acb/Caching%20Application%20Block.msi

Там есть полные исходники длл и кое-какая документация.


Автор: nikf 29.6.2005, 12:18
Мутишь чего-то:
Цитата
Конечно можно и копировать. Вопрос лишь в производительности. Хотелось бы избежать копирования скажем сотни мегабайт памяти.

Цитата
А если придется работать с кучей массивов в цикле и по логике программы всего лишь необходимо вносить изменения в пару элементов каждого массива (но каких, заранее неизвестно)?
ты уж определись, сотни мегов или пара элементов по 8 байт...
если пару елементов - копируй изменяй и записывай обратно.. а про производительность :могу поспорить что решив задачу с отображаемыми файлами ты не заметишь прироста производительности - только время потратишь.. кстати твои 80мегов можешь копировать в память целиком и они
Цитата
сбросится в файл подкачки.
только если только у тя 125 мегов оперативки и параллелно адоб премьер видеофильм сжимает... ИМХО не парься smile

Автор: arilou 30.6.2005, 11:21
Цитата(Guest @ 27.6.2005, 10:32)
С трудом понимаю. С массивом придется работать много и в разных частях программы.

А почему бы не создать класс-обертку вокруг твоих операций над MMF и юзать его "в разных частях программы"? Пусть его члены будут unsafe. Такой паттерн называется "facade", и даст тебе возможность отказаться от MMF, если он тебе все таки не подойдет, не меняя остальную часть программы.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)