2014-01-17 2 views
0

У меня есть программа, которая получает поток необработанных данных с разных камер и записывает их на диск. Программа запускает такие записи в течение ~ 2 минут, а затем для обработки кадров используется другая программа.Написание многих больших файлов быстро в C++

Каждый необработанный кадр составляет 2 МБ, а частота кадров составляет 30 кадров в секунду (то есть скорость передачи данных составляет около 60 МБ/с), и я пишу на SSD, который может легко обрабатывать поддерживаемый> 150 МБ/с (проверен путем копирования 4000 2 МБ файлы с другого диска, которые заняли 38 секунд, и Process Explorer показывает постоянную активность IO).

Моя проблема заключается в том, что иногда звонит fopen(), fwrite() и fclose() киоск на срок до 5 секунд, что означает, что 300MB кадров создать в памяти, как бревно назад, и после того, как некоторые из этих задержек я ударил предел 4 Гб 32-битный процесс. (Когда задержка происходит, Process Explorer показывает разрыв в активности IO)

Существует поток, который запускает цикл вызова этой функции для каждого нового кадра, который добавляется в очередь:

writeFrame(char* data, size_t dataSize, char* filepath) 
{ 
    // Time block 2 
    FILE* pFile = NULL; 
    fopen(&pFile, filepath, "wb"); 
    // End Time block 2 

    // Time block 3 
    fwrite(data,1,dataSize,pFile); 
    // End Time block 3 

    // Time block 4 
    fclose(pFile); 
    // End Time block 4 
} 

(Там в ошибка проверки тоже в фактическом коде, но это не имеет никакого отношения к этой проблеме) Я регистрирую время, которое требуется для каждого из блоков, и общее время, необходимое для запуска функции, и я получаю результаты, которые в большинстве случаев выглядят например: (раз в мс)

TotalT,5,  FOpenT,1,  FWriteT,2, FCloseT,2 
TotalT,4,  FOpenT,1,  FWriteT,1, FCloseT,2 
TotalT,5,  FOpenT,1,  FWriteT,2, FCloseT,2 

т.е. ~ 5 мс для запуска целых функций, ~ 1 мс для открытия файла, ~ 2 мс для вызова записи и ~ 2 мс для закрытия файла.

Однако иногда (в среднем около 1 на каждые 50 кадров, но иногда это может быть тысячи кадров между этой проблемой происходящего), я получаю кадры, которые принимают более 4000ms:

TotalT,4032, FOpenT,4023, FWriteT,6, FCloseT,3 

и

TotalT,1533, FOpenT,1,  FWriteT,2, FCloseT,1530 

Все кадры имеют одинаковый размер, и его никогда не fwrite что берет дополнительное время, всегда fopen или fclose

Никакой другой процесс не читает/не записывает/не записывает этот SSD (подтвержденный с помощью Process Monitor).

Кто-нибудь знает, что может быть причиной этой проблемы и/или любым способом избежать/смягчить эту проблему?

+0

Каждый кадр записывается в отдельный файл? Возможно, вы могли бы записывать группы кадров в один файл и иметь отдельный поток, который обрабатывает их, чтобы впоследствии взять файл из N кадров и сегментировать их в отдельные файлы (чтобы облегчить вызовы fopen/fclose в потоке обработки видео). Тогда это позволит вашей функции writeFrame работать намного быстрее и не замедлять процесс захвата видео. – spartygw

+0

рассмотрите проверку того, что 'fopen' и' fclose' действительно успешно открываются и закрываются, также проверяют, сколько потоков запущено, возможно, вы нажимаете максимальную величину потока. –

+1

Вы не упомянули о платформе или типе файловой системы, используемом на ssd. Если это окна, это будет хорошее место для использования асинхронных записей. – Dan

ответ

1

Я собираюсь присоединиться к X.J., вы, вероятно, пишете слишком много файлов в один каталог. Решением может быть создание нового каталога для каждой партии кадров. Также подумайте о вызове SetEndOfFile непосредственно после создания файла, так как это поможет Windows выделить достаточное пространство за одну операцию.

FAT не является реальным решением, поскольку он еще хуже работает на больших каталогах.

1

Подготовить пустые файлы (2 МБ файлов, заполненных нулями). Таким образом, пространство уже «готово», а затем просто перезапишите эти файлы. Или создайте файл, который представляет собой пакет из нескольких кадров, поэтому вы можете уменьшить количество файлов.

есть библиотеки для делать сжатие и декомпрессию и воспроизведение видео:

libTheora может быть полезным, потому что уже сжимать кадры (а вам нужно выводить видео в одном файле) и сделать это довольно быстро (с потерями сжатие между прочим).

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