Das Schreiben mehrerer Dateien wird nach x Sekunden verlangsamt

8

Ich habe Code, der Frames von einer Kamera bekommt und dann auf die Festplatte speichert. Die Struktur des Codes ist: mehrere Threads malloc und kopieren Sie ihre Frames in neuen Speicher, Speicher in die Warteschlange. Schließlich entfernt ein anderer Thread Frames aus der Warteschlange und schreibt sie (unter Verwendung der ffmpeg-API, Rohvideo ohne Komprimierung) in ihre Dateien (tatsächlich verwende ich meinen eigenen Speicherpool, so dass Malloc nur aufgerufen wird, wenn ich mehr Puffer benötige). Ich kann bis zu 8 Dateien gleichzeitig öffnen.

Das Problem ist, dass in den ersten 45 Sekunden alles gut funktioniert: Es gibt nie mehr als einen Frame in der Warteschlange. Aber danach wird meine Warteschlange gesichert, die Verarbeitung dauert nur ein paar Millisekunden länger, was zu einer erhöhten Ram-Nutzung führt, weil ich die Frames nicht schnell genug speichern kann, so dass ich mehr Speicher ma- lokomieren muss, um sie zu speichern.

Ich habe einen 8-Core-, 16-GB-RAM Windows 7 64-Bit-Computer (NTFS, viel freier Speicherplatz im zweiten Laufwerk). Die Diskette soll bis zu 6Gbits / sec schreiben können. Um meine Daten rechtzeitig zu speichern, muss ich mit 50 MB / s schreiben können. Ich habe die Geschwindigkeit der Festplatte mit "PassMark PerformanceTest" getestet und ich hatte 8 Threads, die Dateien gleichzeitig schreiben, genau wie ffmpeg Dateien speichert (synchronisierte, nicht zwischengespeicherte I / O) und 100MB / Sek. Erreichen konnte. Warum können meine Autoren das nicht erreichen?

So sehen die ffmpeg-Schreibvorgänge aus den Überwachungsprotokollen des Prozesses aus:

%Vor%

Das sieht sehr effizient aus, aber von DiskMon schauen die tatsächlichen Festplattenschreibvorgänge lächerlich fragmentiert hin und her, was für diese langsame Geschwindigkeit verantwortlich ist. Siehe Diagramm für die Schreibgeschwindigkeit gemäß diesen Daten (~ 5 MB / s).

%Vor%

Ich bin ziemlich sicher, dass es nicht mein Code ist, weil ich alles zeitlich abgestimmt habe und zum Beispiel ein paar von uns eingib, was andeutet, dass Threads nicht warten, bis sie aufeinander warten. Es muss die Festplatte schreiben. Die Frage ist also, wie ich meine Festplattenschreibvorgänge verbessern kann und was ich tun kann, um tatsächliche Festplattenschreibvorgänge zu profilieren (beachte, dass ich FFmpeg dlls zum Speichern benötige, damit ich nicht direkt auf die Schreibfunktionen auf niedriger Ebene zugreifen kann). Wenn ich es nicht herausfinden kann, werde ich alle Frames in einer einzelnen sequenziellen Binärdatei ablegen (was die I / O-Geschwindigkeit erhöhen sollte) und sie dann in Videodateien nach der Verarbeitung aufteilen.

Ich weiß nicht, wie viel meine Platten-E / A zwischenspeichert (CacheSet zeigt nur C-Cachegröße an), aber das folgende Bild aus dem Performance-Monitor wird bei 0 und 45 Sekunden in das Video aufgenommen (kurz bevor meine Warteschlange startet) häufen sich) sieht mir komisch aus. Im Grunde genommen ist die Menge an modifiziertem Set und Standby von sehr wenig auf diesen großen Wert angewachsen. Werden die Daten zwischengespeichert? Ist es möglich, dass Daten erst nach 45 Sekunden auf die Festplatte geschrieben werden und plötzlich alles langsamer wird? (FYI, LabVIEW ist das Programm, das meine DLL lädt.)

Ich werde jede Hilfe zu schätzen wissen.
M.

    
Matt 24.08.2011, 06:45
quelle

2 Antworten

2

Das Problem ist mit den wiederholten malloc und free , die das System belasten. Ich schlage vor, einen Pufferpool zu erstellen, d. H. N-Puffer in der Initialisierungsphase zuzuweisen und sie wiederzuverwenden, anstatt den Speicher zu mallocieren und freizugeben. Da Sie ffmpeg erwähnt haben, um ein Beispiel aus Multimedia zu geben, In gstreamer, findet die Pufferverwaltung in Form von puffer-pools und in einer gstreamer-Pipeline werden normalerweise Puffer aus Pufferpools übernommen. Die meisten Multimedia-Systeme tun dies.

Betreffend:

The problem is that for the first 45 sec everything works fine: there's never more than one frame on queue. But after that my queue gets backed up, processing takes just a few ms longer resulting in increased ram usage because I cannot save the frames fast enough so I have to malloc more memory to store them.

Die Anwendung ist zu diesem Zeitpunkt trashing . Wenn Sie an dieser Stelle malloc aufrufen, wird das noch schlimmer. Ich schlage vor, ein Produzenten-Konsumenten-Modell zu implementieren, bei dem einer von ihnen je nach Fall wartet. In Ihrem Fall richten Sie einen Schwellenwert von N Puffern ein. Wenn sich in der Warteschlange N Puffer befinden, werden neue Bilder von der Kamera nicht in die Warteschlange eingereiht, bis die vorhandenen Puffer verarbeitet sind.

Eine andere Idee, anstatt rohe Frames zu schreiben, warum nicht codierte Daten schreiben? Angenommen, Sie wollen ein Video, können Sie zumindest einen elementaren H264-Stream schreiben (und ffmpeg kommt mit einem guten H264-Encoder!) oder noch besser, wenn Sie Zugriff auf einen Mpeg-4-Muxer haben, als mp4-Datei? Dies wird die Speicheranforderungen und die E / A-Last dramatisch reduzieren.

    
vine'th 24.08.2011, 07:06
quelle
3

Mit CreateFile sieht es so aus, als ob Sie es wollen einer oder beide dieser Parameter:

  • FILE_FLAG_NO_BUFFERING
  • FILE_FLAG_WRITE_THROUGH

Ссылка

Ihr verzögerter Leistungseinbruch tritt auf, wenn das Betriebssystem beginnt, Daten auf die Festplatte zu übertragen.

6Gb / s ist die Leistungsfähigkeit des SATA 2-Busses, nicht die tatsächlichen angeschlossenen Geräte oder die physischen Platten oder Flash-RAMs darunter.

Ein häufiges Problem bei AV-Systemen ist das ständige Schreiben eines hohen Datenstroms, der periodisch durch Festplatten-Overhead-Aufgaben unterbrochen werden kann. Früher gab es spezielle AV-Disketten, die Sie kaufen können, die das nicht tun. Heutzutage können Sie Disketten mit spezieller Hochdurchsatz-Leistungsfirmware explizit für die Sicherheitsvideoaufzeichnung kaufen.

Ссылка

    
Steve-o 24.08.2011 06:52
quelle

Tags und Links