У меня есть программа, которая получает поток необработанных данных с разных камер и записывает их на диск. Программа запускает записи такого рода в течение ~ 2 минут, а затем другая программа используется для обработки кадров.
Каждый необработанный кадр составляет 2 МБ, а частота кадров составляет 30 кадров в секунду (т. Е. Скорость передачи данных составляет около 60 МБ / с), и я пишу на твердотельный накопитель, который может легко выдерживать устойчивые> 150 МБ / с (проверено путем копирования 4000 файлов 2 МБ с другого диска). что заняло 38 секунд и Process Explorer показывает постоянную активность ввода-вывода).
Моя проблема в том, что иногда звонит fopen()
, fwrite()
а также fclose()
Останавливается на 5 секунд, что означает, что 300 МБ кадров накапливаются в памяти как обратный журнал, и после нескольких из этих задержек я достиг предела 4 ГБ 32-битного процесса. (Когда происходит задержка, Process Explorer показывает разрыв в активности ввода-вывода)
Существует поток, который запускает цикл, вызывающий эту функцию для каждого нового кадра, который добавляется в очередь:
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 кадров, но иногда это может быть тысячи кадров между этой проблемой), я получаю кадры, которые занимают более 4000 мс:
TotalT,4032, FOpenT,4023, FWriteT,6, FCloseT,3
а также
TotalT,1533, FOpenT,1, FWriteT,2, FCloseT,1530
Все кадры одинакового размера и никогда fwrite
это занимает дополнительное время, всегда fopen
или же fclose
Никакой другой процесс не читает / записывает на / с этого SSD (подтверждено с помощью Process Monitor).
Кто-нибудь знает, что может быть причиной этой проблемы и / или каким-либо образом избежать / смягчить эту проблему?
Я собираюсь поддержать X.J., вы, вероятно, пишете слишком много файлов в один каталог.
Решением может быть создание нового каталога для каждой партии кадров. Также рассмотрите возможность вызова SetEndOfFile
непосредственно после создания файла, поскольку это поможет Windows выделить достаточно места за одну операцию.
FAT не является реальным решением, так как он работает еще хуже на больших каталогах.
Подготовьте пустые файлы (файлы размером 2 МБ, заполненные нулями), чтобы пространство уже было «готово», а затем просто перезапишите эти файлы. Или создайте файл, состоящий из нескольких кадров, чтобы уменьшить количество файлов.
Существуют библиотеки для сжатия, распаковки и воспроизведения видео:
libTheora может быть полезна, потому что уже сжимает кадры (ну, вам нужно вывести видео в одном файле) и делать это довольно быстро (кстати, сжатие с потерями).