|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » .NET - MemoryMappedFile & ReadFile |
|
.NET - MemoryMappedFile & ReadFile
|
Пользователь Сообщения: 107 |
Добрый день.
В общем задание - сравнить скорость чтения отображенного в ОЗУ файла и просто напрямую с диска через ReadFile. ("Сравнить среднее время доступа к данным в файле при использовании метода отображения файла на адресное пространство процесса и при использовании традиционного доступа к файлу с использованием системного вызова ReadFile.") Погуглил погуглил и MSDN и пр. мне сказали что отображением файла занимается класс MemoryMappingFile. Вроде прогу написал, всё работает. НО ReadFile (который как я понял считывает с харда напрямую?) работает БЫСТРЕЕ чем в случае отображения файла. using System; using System.IO; using System.IO.MemoryMappedFiles; using System.Runtime.InteropServices; // для вызова функций из WinAPI using System.Timers; namespace mapping1 { class Program { [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] unsafe static extern bool ReadFile ( IntPtr hFile, void* lpBuffer, int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, IntPtr lpOverlapped ); struct s1 { public int[] mas1;} // 1 MB struct s20 { public int[] mas2;} // 20 MB struct s512 { public int[] mas3;} // 256 MB static void Main() { s1 Sc1; Sc1.mas1 = new int[262144]; // 1 MB s20 Sc2; Sc2.mas2 = new int[5242880]; // 20 MB s512 Sc3; Sc3.mas3 = new int[67108864]; // 256 MB long offset1 = 0x0000000; // смещение для CreateViewAccessor long length1 = 0x0100000; // 1 mb long offset2 = 0x00A00000; // 10 MB long length2 = 0x01400000; // 20 MB long offset3 = 0x10000000; // 256 MB long length3 = 0x10000000; // 256 MB long time1 = 0; long time2 = 0; long time3 = 0; Console.ReadKey(); using (var mmf1 = MemoryMappedFile.CreateFromFile(@"C:\Users\xxx\Documents\Visual Studio 2010\Projects\sizetests1\sizetests1\bin\Debug\Test.data", FileMode.Open, "file1")) { // Create a random access view, from the 256th megabyte (the offset) // to the 512th megabyte (the offset plus length). using (var accessor1 = mmf1.CreateViewAccessor(offset1, length1)) { Console.WriteLine("Mapping and reading from mapped file..."); Console.WriteLine("Mapped to RAM: " + (accessor1.Capacity / (1024 * 1024)) + " megabytes"); long a1 = DateTime.Now.Ticks; accessor1.ReadArray<int>(0, Sc3.mas3, 0, 262144); // 1 mb long a2 = DateTime.Now.Ticks; time1 = (a2 - a1) / 10000; // milliseconds Console.WriteLine("Reading time: " + time1 + " milliseconds\n"); } mmf1.Dispose(); // освобождает все ресурсы, использумые mmf1 } using (var mmf2 = MemoryMappedFile.CreateFromFile(@"C:\Users\xxx\Documents\Visual Studio 2010\Projects\sizetests1\sizetests1\bin\Debug\Test.data", FileMode.Open, "file1")) { using (var accessor1 = mmf2.CreateViewAccessor(offset2, length2)) { Console.WriteLine("Mapped to RAM: " + (accessor1.Capacity / (1024 * 1024)) + " megabytes"); long a1 = DateTime.Now.Ticks; accessor1.ReadArray<int>(0, Sc2.mas2, 0, 5242880); // 20 mb long a2 = DateTime.Now.Ticks; time2 = (a2 - a1) / 10000; // milliseconds Console.WriteLine("Reading time: " + time2 + " milliseconds\n"); } mmf2.Dispose(); // освобождает все ресурсы, использумые mmf2 } using (var mmf3 = MemoryMappedFile.CreateFromFile(@"C:\Users\xxx\Documents\Visual Studio 2010\Projects\sizetests1\sizetests1\bin\Debug\Test.data", FileMode.Open, "file1")) { using (var accessor1 = mmf3.CreateViewAccessor(offset3, length3)) { Console.WriteLine("Mapped to RAM: " + (accessor1.Capacity / (1024 * 1024)) + " megabytes"); long a1 = DateTime.Now.Ticks; accessor1.ReadArray<int>(0, Sc3.mas3, 0, 67108864); // 256 mb long a2 = DateTime.Now.Ticks; time3 = (a2 - a1) / 10000; // milliseconds Console.WriteLine("Reading time: " + time3 + " milliseconds\n"); } mmf3.Dispose(); // освобождает все ресурсы, использумые mmf3 } // принудительная сборка мусора GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.GetTotalMemory(true); Console.ReadKey(); // part2 : directly from hdd long time_1 = 0; long time_2 = 0; long time_3 = 0; int length_1 = 262144; int length_2 = 5242880; int length_3 = 67108864; length_1 *= sizeof(int); length_2 *= sizeof(int); length_3 *= sizeof(int); Console.WriteLine("Reading from HDD..."); using (var fs1 = File.Open(@"C:\Users\xxx\Documents\Visual Studio 2010\Projects\sizetests1\sizetests1\bin\Debug\Test.data", FileMode.Open, FileAccess.Read)) { unsafe { fixed (int* pointerForArray = Sc1.mas_1) { long a1 = DateTime.Now.Ticks; ReadFile(fs1.Handle, pointerForArray, length_1, ref length_1, IntPtr.Zero); long a2 = DateTime.Now.Ticks; time_1 = (a2 - a1) / 10000; // milliseconds } Console.WriteLine("First block readed success. Time:" + time_1); fixed (int* pointerForArray = Sc2.mas_2) { long a1 = DateTime.Now.Ticks; ReadFile(fs1.Handle, pointerForArray, length_2, ref length_2, IntPtr.Zero); long a2 = DateTime.Now.Ticks; time_2 = (a2 - a1) / 10000; // milliseconds } Console.WriteLine("Second block readed success. Time:" + time_2); fixed (int* pointerForArray = Sc3.mas_3) { long a1 = DateTime.Now.Ticks; ReadFile(fs1.Handle, pointerForArray, length_3, ref length_3, IntPtr.Zero); long a2 = DateTime.Now.Ticks; time_3 = (a2 - a1) / 10000; // milliseconds } Console.WriteLine("Third block readed success. Time:" + time_3); } fs1.Dispose(); fs1.Close(); } Console.WriteLine("Statistics:\nwith mapping (from RAM): " + time1 + " " + time2 + " " + time3 + "\nwithout mapping (from HDD): " + time_1 + " " + time_2 + " " + time_3); Console.ReadKey(); } } } Mapped to RAM: 1 megabytes Reading time: 3 milliseconds Mapped to RAM: 20 megabytes Reading time: 70 milliseconds Mapped to RAM: 256 megabytes Reading time: 836 milliseconds Reading from HDD... First block readed success. Time:0 Second block readed success. Time:12 Third block readed success. Time:173 Statistics: with mapping (from RAM): 3 70 836 without mapping (from HDD): 0 12 173 WTF?.... Вроде сборщик мусора принудительно запускал, но память не очищается - до первого ReadKey прога весит в озу 19 мб, до второго ReadKey 300 мб, до третьего (в итоге) - примерно 570 Мб. |
|
Отправлено: 09:49, 19-11-2011 |
Необычный Сообщения: 4463
|
Профиль | Сайт | Отправить PM | Цитировать Цитата Sidewalker:
Цитата Sidewalker:
Что тебя спрашивают? Правильно! "Сравнить среднее время доступа к данным в файле(1) при использовании метода отображения файла(2) на адресное пространство процесса и при использовании традиционного доступа к файлу(3) с использованием системного вызова ReadFile." Объясни мне, какое отношение написанный код имеет к скорости чтения файлов и мапирования их в память? Отвечу - никакого! То, что ты написал - подготовительный этап тестирования. Да, мапирование дольше, т.к. там 1 - чтение файла с медленного HDD, 2 - запись данных в ОЗУ (+накладные расходы, выделения памяти, менеджера памяти и т.д.). Чтение - это просто чтение. ---- Вот сейчас, когда у тебя файл на hdd и его дубликат в памяти, проводи тесты на скорость линейного доступа, случайного доступа. Получишь графики - объясняй их форму, характер и т.д. Вот это - курсовая. А то что у тебя сейчас есть - это подготовительный этап, важный, но подготовительный. От него зависит, как именно файл будет расположен в памяти, и как файл будет расположен на hdd. Это исходные данные. ---- Беглый просмотр кода, позволяет тебя поздравить с выполнением этого этапа. Теперь самое интересное - тесты на скорость доступа. Успехов! |
||
------- Отправлено: 10:25, 19-11-2011 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Пользователь Сообщения: 107
|
Цитата lxa85:
Цитата Sidewalker:
Цитата Sidewalker:
Цитата lxa85:
Цитата lxa85:
long a1 = DateTime.Now.Ticks; accessor1.ReadArray<int>(0, Sc3.mas3, 0, 262144); // 1 mb long a2 = DateTime.Now.Ticks; time1 = (a2 - a1) / 10000; // milliseconds ? Чем не тест? |
|||||
Последний раз редактировалось Sidewalker, 18-07-2020 в 17:04. Отправлено: 10:31, 19-11-2011 | #3 |
Необычный Сообщения: 4463
|
Профиль | Сайт | Отправить PM | Цитировать ок.
Цитата Sidewalker:
Что куда попадает, в какой структурной форме (уровнем асбтракции) и т.п. Т.е. у меня сейчас предположение, что тут "навёрнута" слишком дурацкая конструкция со множеством "вложенностей" (var mmf1 = MemoryMappedFile.CreateFromFile(@"C:\Users\RazoR\Documents\Visual Studio 2010\Projects\sizetests1\sizetests1\bin\Debug\Test.data", FileMode.Open, "file1") Что это? Еще одна ссылка на внешний объект? Где в коде можно поставить точку и сказать, что "Вот. Вот здесь мы получили "чистую" копию файла в памяти"? Проверь, что не идет динамического обращения к дисковой подсистеме. Постарайся вообще убрать всякую оптимизацию кода компилятором. А то кто эти компиляторы .NET знает, вполне могли оптимизировать. Это еще что такое? Причем здесь Sc3.mas3 ? Ладно, спишем, как опечатку. ---- Цитата Sidewalker:
|
||
------- Отправлено: 10:55, 19-11-2011 | #4 |
Пользователь Сообщения: 107
|
Цитата lxa85:
Цитата lxa85:
CreateViewAccessor() - Создает метод MemoryMappedViewAccessor, который соответствует представлению размещенного в памяти файла. Внизу ссылки - пример. http://msdn.microsoft.com/ru-ru/libr...appedfile.aspx Так что насчёт "дурацкая конструкция" - всё к мелкософту. Цитата lxa85:
Цитата lxa85:
Цитата lxa85:
|
||||||
Отправлено: 14:48, 19-11-2011 | #5 |
Необычный Сообщения: 4463
|
Профиль | Сайт | Отправить PM | Цитировать Цитата Sidewalker:
Цитата Sidewalker:
У меня вопрос тот же. Поставить пальцем точку в листинге программы и сказать, что "От сих мы работаем только с ОЗУ". И разумеется обосновать свое решение. Хорошо бы вообще отключить физический доступ к носителю, после того, как файл был скопирован в память. BTW имеет ли разницу слова "скопировать файл в память" и "смапировал/отобразил файл в память"? ---- На предзащите гораздо интереснее смотреть толковый график, нежели всматриваться в микро(очень маленькую? )статистику с колонками цифр. |
||
------- Отправлено: 15:22, 19-11-2011 | #6 |
Пользователь Сообщения: 107
|
Цитата lxa85:
Цитата lxa85:
Цитата Sidewalker:
Цитата lxa85:
В общем. Проблема решилась. Дело было в том, что при таком Цитата Sidewalker:
|
|||||
Последний раз редактировалось Sidewalker, 18-07-2020 в 17:04. Отправлено: 19:29, 19-11-2011 | #7 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Apple iPod Touch 4G && Jailbreak - все еще нужно? | mmx358 | Мобильные ОС, смартфоны и планшеты | 8 | 29-03-2011 10:00 | |
Драйвер - PCI\VEN_1095&DEV_3132&SUBSYS_71321095&REV_01\4&662654C&0&00E0 | kalion-kill | Поиск драйверов, прошивок и руководств | 1 | 08-11-2009 16:45 | |
Функция ReadFile | DillerInc | Программирование и базы данных | 8 | 18-07-2005 07:45 | |
WinXP & Win2K & Net & Inet проблема!! Help! | SDL2000 | Сетевые технологии | 5 | 19-10-2003 22:29 |
|