2015-07-31 4 views
1

Я прочитал немало сообщений SO и общих статей о попытке выделить более 1 ГБ памяти, поэтому перед тем, как сбить, как и другие, вот какой-то контекст.Память сопоставленных файлов, которые смежны на диске

Это приложение будет работать как киоск с выделенной машиной без ненужных процессов.

Мое приложение приобретает изображения с высокоскоростной камеры с рулоном затвором со скоростью 120 кадров в секунду с разрешением 1920 x 1080 с глубиной в 24 единицы. Приложение должно записывать каждый отдельный кадр на диск для последующей обработки. Текущая проблема, с которой я сталкиваюсь, заключается в том, что дисковый ввод-вывод не будет поддерживать скорость захвата, даже если он ограничен 120 кадрами в секунду. Необходимая ширина дискового ввода-вывода составляет около 750 Мбит/с!

Общая длина записи должна быть не менее 10 секунд (7,5 ГБ) в необработанном виде. Выполнение любого транскодирования или сжатия «на лету» приводит к снижению частоты кадров до совершенно неприемлемых уровней.

Чтобы обойти эту проблему, я попытался следующие:

  • Компромат на качество за счет уменьшения битовой глубины на аппаратном уровне до 16, которые до сих пор вокруг 500Mbps.
  • Отключено все кодирование изображения и запись необработанных данных камеры на диск. Это сэкономило время обработки.
  • Создание одного файла объемом 10 ГБ на диске и выполнение последовательной записи в виде фреймов. Это помогло до сих пор. Для всех приложений и систем производства имеется специальный накопитель на 100 ГБ для этого приложения.
  • Использование Contig.exe из Sysinternals для дефрагментации файла. Это привело к поразительным успехам на дисках, отличных от SSD.

Невозможно изучить здесь. Я не знаком с файлами с отображением памяти и при попытке их создания получаю сообщение об ошибке IOException Not enough storage is available to process this command..

using (var file = MemoryMappedFile.CreateFromFile(@"D:\Temp.VideoCache", FileMode.OpenOrCreate, "MyMapName", int.MaxValue, MemoryMappedFileAccess.CopyOnWrite)) 
{ 
    ... 
} 

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

Я мог бы даже заставить общий размер записи до 1,8 ГБ, если только был способ выделить столько ОЗУ. Еще раз, это будет работать на выделенном 8 ГБ доступной памяти и 100 ГБ свободного места. Однако не все производственные системы будут иметь накопители SSD.

+5

Очевидно, что производственной системе нужен либо диск, который может обрабатывать пропускную способность, либо достаточно памяти для хранения переполнения в памяти, ожидая, когда диск обработает нагрузку? Разве это не все, что нужно? Если вы не пишете свою собственную файловую систему или не говорите изначально в NTFS или в конкретной файловой системе, нет простого способа гарантировать непрерывный файл. –

+1

Что вы думаете? – CodeCaster

+0

Вы, конечно, можете выделить столько (1,8 ГБ) ОЗУ. 64-битные процессы и функции выделения Win32 (на машине с достаточным объемом оперативной памяти). Но в конце вам нужна дисковая система с достаточной производительностью. – Richard

ответ

1

32-разрядные процессы в 64-разрядной системе могут выделять 4 ГБ ОЗУ, поэтому для хранения видео должно быть возможно получить 1,8 ГБ ОЗУ, но, конечно же, вам необходимо рассмотреть загруженные библиотеки DLL и буфер до тех пор, пока видео сжимается.

Кроме этого, вы можете использовать RAMDisk, например. от DataRam. Вам просто нужно найти баланс между объемом памяти приложения и количеством памяти, которую вы можете предоставить на диске. ИМХО: настройка 5 ГБ/3 ГБ может работать хорошо: 1 ГБ для ОС, 4 ГБ для вашего приложения и 3 ГБ для файла.

Не забудьте скопировать файл с RAM-диска на жесткий диск, если вы хотите, чтобы он был постоянным.

+0

Спасибо, Томас. RAMDisk выглядит очень многообещающим. Я попробую его и вернусь обратно. Что касается вашего первого момента, я не нашел способа выделить более 600 МБ ОЗУ программно. Даже ответ xanatos, по-видимому, указывает на то, что файлы MM не будут ускорять последовательные сценарии записи. Если есть неуправляемые вызовы, которые я мог бы использовать, чтобы получить больше памяти, это было бы здорово. Приложение является 32-битным и будет ВСЕГДА работать на 64-битных операционных системах. –

+0

Возможно, вы можете получить только 600 МБ непрерывной оперативной памяти из-за фрагментации памяти. Попробуйте выделить 100 МБ несколько раз. Думаю, вы можете выделить память для одиночных кадров (n * 8MB) и не нуждаться в одном большом блоке (1800 МБ). –

1

Товарная техника дешево по причине. Вам нужно быстрее аппаратное обеспечение.

Купить более быстрый диск system. Хороший RAID-контроллер и четыре SSD. Поместите диски в конфигурацию RAID 1 + 0 и сделайте это с этой проблемой.

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

1
  1. памяти отображаются файлы не ускорить очень много писать в файл ...

  2. Если у вас есть большой файл, вы обычно не пытаются отобразить его полностью в оперативной памяти. ..вы карту «окно» его, а затем «шаг» окно (в C#/Windows API вы создаете «представление» файла, начиная с любого одном месте и с определенным размером)

Пример код: (здесь окно 1mb большое ... большие окна можно ... в 32 бит должно быть возможным выделить окно в 64 или 128МБ без каких-либо проблем)

const string fileName = "Test.bin"; 
const long fileSize = 1024L * 1024 * 16; 
const long windowSize = 1024 * 1024; 

if (!File.Exists(fileName)) { 
    using (var file = File.Create(fileName)) { 
     file.SetLength(fileSize); 
    } 
} 

long realFileSize = new FileInfo(fileName).Length; 

if (realFileSize < fileSize) { 
    using (var file = File.Create(fileName)) { 
     file.SetLength(fileSize); 
    } 
} 

using (var mm = MemoryMappedFile.CreateFromFile(fileName, FileMode.Open)) { 
    long start = 0; 

    while (true) { 
     long size = Math.Min(fileSize - start, windowSize); 

     if (size <= 0) { 
      break; 
     } 

     using (var acc = mm.CreateViewAccessor(start, size)) { 
      for (int i = 0; i < size; i++) { 
       // It is probably faster if you write the file with 
       // acc.WriteArray() 
       acc.Write(i, (byte)i); 
      } 
     } 

     start += windowSize; 
    } 
} 

Обратите внимание, что здесь я записывая код, который будет записывать фиксированное заранее известное количество байтов (fileSize) ... Ваш код должен быть другим (потому что вы не можете заранее знать «точный» fileSize). Все еще помнят: Файлы с отображением памяти не ускоряют запись в файл.

+0

Спасибо. Образец кода дает прекрасный обзор для начала работы с файлами MM. Я все еще пытаюсь понять, как я мог бы оптимизировать их для последовательных сквозных писем около 500 Мбит/с. Я имею как минимум 8 ГБ доступной памяти, и не возражаю, если он останется использованным в течение 10 секунд записи. И да, я знаю заранее ожидаемый размер файла (5 ГБ на 10 секунд), если это помогает оптимизировать использование ОЗУ. –

+0

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

Смежные вопросы