Проблема следующая:
Видеопоток покадрово помещается в ОЗУ по известному адресу.
Требуется с МАКСИМАЛЬНОЙ скоростью записать его на диск.
Попробовал через FileMapping. В файл пишу блоки по 64Кб с использованием MapViewOfFile/UnMapViewOfFile. Итоговый размер файла — около 10Гб.
При последовательности MapViewOfFile — memcpy() — UnMapViewOfFile память (512 Мб) съедается на 5-м Гбайте файла, а при последовательности MapViewOfFile — memcpy() — FlushViewOfFile — UnMapViewOfFile с памятью все в порядке, но скорость падает раза в 3 .
Кто может подсказать способ избавления от занятой MapViewOfFile памяти???
PLEEEEEASE
Ho>При последовательности MapViewOfFile — memcpy() — UnMapViewOfFile память (512 Мб) съедается на 5-м Гбайте файла, а при последовательности MapViewOfFile — memcpy() — FlushViewOfFile — UnMapViewOfFile с памятью все в порядке, но скорость падает раза в 3 .
Ho>Кто может подсказать способ избавления от занятой MapViewOfFile памяти??? Ho>PLEEEEEASE
Я делал FlushViewOfFile в другой нити — это избавляло от тормозов.
Здравствуйте Ho, Вы писали:
Ho>А что значит "в другой нити" — в другом потоке или как?
Да, в другом потоке.
В моем случае было проще – размер файла был меньше 2GB. И мне надо было его потихоньку заполнять, читая последнее записанное. Тогда я периодически вызывал:
Реализовал этот код – теряется вся прелесть последовательного доступа к диску (что, по идее, и должно обеспечивать максимальную скорость записи), т.к. процесс FlushViewOfFile рассинхронизизирован с родительским процессом.
Попробовал синхронизировать родительский поток с дочерним – после вызова Flush() поставил WaitForSingleObject(…). Эффект получился немного хуже, чет от простого вызова FlushViewOfFile :crash: .
Предлагаю следущую стратегию:
Когда блок заполнился — основной поток открывает новый блок с помощью MapViewOfFile, и пишет в него, а другая нить в это время делает со старым блоком FlushViewOfFile — UnMapViewOfFile
Здравствуйте Андрей Ш, Вы писали:
АШ>Предлагаю следущую стратегию: АШ>Когда блок заполнился — основной поток открывает новый блок с помощью MapViewOfFile, и пишет в него, а другая нить в это время делает со старым блоком FlushViewOfFile — UnMapViewOfFile
Идея замечательная :up: . Большущее :) спасибо!!!
АШ>И блок можно бы сделать побольше (>=1MB).
Сейчас пробую варьировать размер блока от 10 до 50 Mb — смотрю, как себя при этом ведет память.
О результатах сообщу в обязательном порядке.
Еще такой вопрос: потоки, которые я создаю для FlushViewOfFile и UnMapViewOfFile, выполняются последовательно или параллельно? Я имею в виду следующее: не надо ли принудительно их (потоки) синхронизировать, чтобы головки диска не скакали по поверхности (при переключении между потоками), а шли последовательно.
Ho>Еще такой вопрос: потоки, которые я создаю для FlushViewOfFile и UnMapViewOfFile, выполняются последовательно или параллельно? Я имею в виду следующее: не надо ли принудительно их (потоки) синхронизировать, чтобы головки диска не скакали по поверхности (при переключении между потоками), а шли последовательно.
Это зависит от того, сколько процессоров на машине. Если 1, то последовательно, если >1 — возможно параллельно.
Ho>Еще такой вопрос: потоки, которые я создаю для FlushViewOfFile и UnMapViewOfFile, выполняются последовательно или параллельно? Я имею в виду следующее: не надо ли принудительно их (потоки) синхронизировать, чтобы головки диска не скакали по поверхности (при переключении между потоками), а шли последовательно.
Синхронизировать не надо. Запись на диск старого буфера и заполнение в памяти нового может происходить одновременно даже на компьютере с одним процессором — в этом и состоит выигрыш.
Здравствуйте Ho, Вы писали:
Ho>Проблема следующая: Ho>Видеопоток покадрово помещается в ОЗУ по известному адресу. Ho>Требуется с МАКСИМАЛЬНОЙ скоростью записать его на диск.
Ho>Попробовал через FileMapping. В файл пишу блоки по 64Кб с использованием MapViewOfFile/UnMapViewOfFile. Итоговый размер файла — около 10Гб.
Ho>При последовательности MapViewOfFile — memcpy() — UnMapViewOfFile память (512 Мб) съедается на 5-м Гбайте файла, а при последовательности MapViewOfFile — memcpy() — FlushViewOfFile — UnMapViewOfFile с памятью все в порядке, но скорость падает раза в 3 .
Ho>Кто может подсказать способ избавления от занятой MapViewOfFile памяти??? Ho>PLEEEEEASE
Ну во первых, помоем удостичь высокой скорости в записи при помощи FileMaping вообще невозможно.
Эти функции не для того предназначены.
Лучше всего старые добрые WriteFile....С флагом без кеширования.
Вот так вот.
Здравствуйте Ho, Вы писали:
Ho>Проблема следующая: Ho>Видеопоток покадрово помещается в ОЗУ по известному адресу. Ho>Требуется с МАКСИМАЛЬНОЙ скоростью записать его на диск.
Ho>Попробовал через FileMapping. В файл пишу блоки по 64Кб с использованием MapViewOfFile/UnMapViewOfFile. Итоговый размер файла — около 10Гб.
Ho>При последовательности MapViewOfFile — memcpy() — UnMapViewOfFile память (512 Мб) съедается на 5-м Гбайте файла, а при последовательности MapViewOfFile — memcpy() — FlushViewOfFile — UnMapViewOfFile с памятью все в порядке, но скорость падает раза в 3 .
А где здесь смысл испльзования FileMapping? Т.е. если я правильно понял, ты считываешь поток не в проекцию файла, а по какому-то другому адресу, а затем копируешь в проекцию. Весь смысл FileMapping'a теряется. Идеально было бы, если бы видеопоток сразу писался в проекцию. В данном случае этого нет. Тогда не лучше ли сразу делать WriteFile твоего буфера (с кадром или с чем там еще)?
Здравствуйте Андрей Ш, Вы писали:
АШ>Синхронизировать не надо. Запись на диск старого буфера и заполнение в памяти нового может происходить одновременно даже на компьютере с одним процессором — в этом и состоит выигрыш.
Параллельное заполнеие одного буфера памяти и запись второго действительно дало заметный прирост производительности. Но я не совсем это имел в виду: допустим, мы создали поток, который пишет старый буфер на диск за N секунд. Затем мы заполнили новый буфер памяти за M секунд, причем M < N (заметно меньше). После этого приложение создает поток, который должен записать на диск новый буфер. Но ведь предыдущий поток записи на диск еще не окончен!
Вот я и хотел узнать, станет новый поток записи на диск в очередь (и дождется его окончания) или попробует начать выполняться одновременно со старым, конкурируя за доступ к диску.
Абсолютно согласен с пред. оратором. Тут проще и эффективнее делать асинхронный WriteFile, можно попробовать FILE_FLAG_SEQUENTIAL_SCAN флаг при создании, хотя и утверждается, что это работает только при чтении.
Успехов.
Ho>>Проблема следующая: Ho>>Видеопоток покадрово помещается в ОЗУ по известному адресу. Ho>>Требуется с МАКСИМАЛЬНОЙ скоростью записать его на диск.
Ho>>Попробовал через FileMapping. В файл пишу блоки по 64Кб с использованием MapViewOfFile/UnMapViewOfFile. Итоговый размер файла — около 10Гб.
Ho>>При последовательности MapViewOfFile — memcpy() — UnMapViewOfFile память (512 Мб) съедается на 5-м Гбайте файла, а при последовательности MapViewOfFile — memcpy() — FlushViewOfFile — UnMapViewOfFile с памятью все в порядке, но скорость падает раза в 3 .
ME>А где здесь смысл испльзования FileMapping? Т.е. если я правильно понял, ты считываешь поток не в проекцию файла, а по какому-то другому адресу, а затем копируешь в проекцию. Весь смысл FileMapping'a теряется. Идеально было бы, если бы видеопоток сразу писался в проекцию. В данном случае этого нет. Тогда не лучше ли сразу делать WriteFile твоего буфера (с кадром или с чем там еще)?
Действительно, WriteFile дает выигрыш в производительности (около 30%). Однако есть такое лицо, называемое начальник и есть такая вещь, называемая ТЗ (то бишь техническое задание). И вот когда данное лицо в данной вещи указывает "... используя FileMapping ..." можно сделать только 3 вещи:
1. Сесть за консоль и расплакаться :no: .
2. Сделать все так, как указано в ТЗ :( .
3. Сделать все так, как указано в ТЗ; найти вариант получше; доказать несостоятельность исходной спецификации и изменить ее.
Мне, почему-то, больше понравился последний вариант :super: .
А то, что пришлось сделать немного больше, так это не страшно: немного набрался опыта, пообщавшись с умными людьми, да и может кому-нибудь пригодится сия информация. А что до потраченного времени, ;) так оно все равно оплачивается...
Начальник? Знаю-знаю, сам бываю таким. А все же попробуй попросить — вдруг скажет, что так и правда лучше.
Удачи.
Ho>Действительно, WriteFile дает выигрыш в производительности (около 30%). Однако есть такое лицо, называемое начальник и есть такая вещь, называемая ТЗ (то бишь техническое задание). И вот когда данное лицо в данной вещи указывает "... используя FileMapping ..." можно сделать только 3 вещи:
Ho>
Ho> 1. Сесть за консоль и расплакаться . Ho> 2. Сделать все так, как указано в ТЗ . Ho> 3. Сделать все так, как указано в ТЗ; найти вариант получше; доказать несостоятельность исходной спецификации и изменить ее. Ho>
Ho>Мне, почему-то, больше понравился последний вариант . Ho>А то, что пришлось сделать немного больше, так это не страшно: немного набрался опыта, пообщавшись с умными людьми, да и может кому-нибудь пригодится сия информация. А что до потраченного времени, так оно все равно оплачивается...
Ho>P.S. Огромное спасибо всем за помощь.