2010-04-07 3 views
6

Okay, also habe ich vorher ein (eher unoptimiertes) Programm geschrieben, um Bilder in JPEGs zu kodieren, aber jetzt arbeite ich mit MPEG-2-Transportströmen und dem H.264-kodierten Video darin. Bevor ich mit dem Programmieren beginne, bin ich gespannt, wie ich am schnellsten mit der eigentlichen Datei umgehen kann.Welches ist schneller im Speicher, ints oder chars? Und Datei-Mapping oder Chunk-Lesen?

Momentan bin ich File-Mapping der .mts-Datei in den Speicher, um daran zu arbeiten, obwohl ich nicht sicher bin, ob es schneller wäre, um zum Beispiel 100 MB der Datei in den Speicher in Blöcken zu lesen und damit umzugehen dieser Weg.

Diese Dateien erfordern eine Menge Bit-Shifting und solche Flags zu lesen, so wundere ich mich, wenn ich einige der Speicher verweisen, wenn es schneller 4 Byte gleichzeitig als Ganzzahl oder 1 Byte als ein Zeichen zu lesen ist . Ich dachte irgendwo, dass x86-Prozessoren auf 4-Byte-Granularität optimiert sind, aber ich bin mir nicht sicher, ob das stimmt ...

Vielen Dank!

Antwort

6

Speichermappedateien sind normalerweise die schnellsten verfügbaren Operationen, wenn Ihre Datei synchron verfügbar sein soll. (Es gibt einige asynchrone APIs, die dem O/S ermöglichen, Dinge für eine leichte Geschwindigkeitserhöhung manchmal neu anzuordnen, aber das klingt, als ob es in Ihrer Anwendung nicht hilfreich ist)

Der Hauptvorteil, den Sie mit den abgebildeten Dateien bekommen, ist das Sie können im Arbeitsspeicher der Datei arbeiten, während sie noch vom O/S von der Festplatte gelesen wird, und Sie müssen nicht Ihren eigenen Sperr-/Thread-Lesecode verwalten.

Speicher Referenz weise, auf dem x86-Speicher wird eine ganze Zeile zu einer Zeit gelesen werden, egal was Sie tatsächlich arbeiten. Die zusätzliche Zeit, die mit nicht-bytegranularen Operationen verbunden ist, bezieht sich auf die Tatsache, dass Ganzzahlen nicht Byte-ausgerichtet sein müssen. Zum Beispiel wird das Ausführen eines ADDs mehr Zeit benötigen, wenn die Dinge nicht an einer 4-Byte-Grenze ausgerichtet sind, aber für so etwas wie eine Speicherkopie wird es wenig Unterschied geben. Wenn Sie mit inhärenten Zeichendaten arbeiten, wird es schneller sein, es so zu behalten, als alles als Ganzzahlen und Bit-Shift-Dinge zu lesen.

Wenn Sie h.264 oder MPEG2-Kodierung machen, wird der Engpass wahrscheinlich in jedem Fall CPU-Zeit und nicht mehr Disk-I/O sein.

2

Wenn Sie auf die gesamte Datei zugreifen müssen, ist es immer schneller, sie in den Speicher einzulesen und dort zu verarbeiten. Natürlich verschwendet es auch Speicher, und Sie müssen die Datei irgendwie sperren, so dass Sie nicht gleichzeitig Zugriff von einer anderen Anwendung erhalten, aber Optimierung geht sowieso um Kompromisse. Die Speicherzuordnung ist schneller, wenn Sie (große) Teile der Datei überspringen, weil Sie sie dann gar nicht lesen müssen.

Ja, der Zugriff auf Speicher mit 4-Byte (oder sogar 8-Byte) Granularität ist schneller als der Zugriff auf Byte-weise. Wieder ist es ein Kompromiss - abhängig davon, was Sie nachher mit den Daten machen müssen und wie geschickt Sie sind, mit den Bits in einem int zu spielen, ist es vielleicht insgesamt nicht schneller.

Wie für alles in Bezug auf die Optimierung:

  1. Maß
  2. optimize
  3. Maß
+0

+1, war es nicht "meassure, meassure, optimieren, meassure wieder"? –

0

auf die beste Größe Bezug aus dem Speicher zu lesen, bin ich sicher, dass Sie this post Lesen genießen über Speicherzugriffsleistung und Cache-Effekte.

1

Dies sind sequentielle Bit-Streams - Sie verbrauchen sie im Prinzip ohne Zutun mit einem Bit zu einem Zeitpunkt.

Sie müssen nicht viel Mühe in die explizite Pufferung von Lesevorgängen und solchen in diesem Szenario investieren: das Betriebssystem wird sie für Sie trotzdem puffern. Ich habe vorher H.264-Parser geschrieben, und die Zeit wird vollständig von der Decodierung und Manipulation dominiert, nicht vom IO.

Meine Empfehlung ist es, eine Standard-Bibliothek zu verwenden und diese Bit-Streams zu analysieren.

Flavor ist solch ein Parser, und die Website enthält auch Beispiele von MPEG-2 (PS) und verschiedenen Teilen, wie H.264 M-Coder. Flavor erstellt nativen Analysecode aus einer C++ - ähnlichen Sprache; hier ist ein Zitat aus der MPEG-2-PS-Spezifikation:

class TargetBackgroundGridDescriptor extends BaseProgramDescriptor : unsigned int(8) tag = 7 
{ 
    unsigned int(14) horizontal_size; 
    unsigned int(14) vertical_size; 
    unsigned int(4) aspect_ratio_information; 
} 

class VideoWindowDescriptor extends BaseProgramDescriptor : unsigned int(8) tag = 8 
{ 
    unsigned int(14) horizontal_offset; 
    unsigned int(14) vertical_offset; 
    unsigned int(4) window_priority; 
} 
0

Eine Sache, über Speicher-Mapping-Dateien zu prüfen, ist, dass eine Datei mit einer Größe von mehr als der verfügbaren Adressbereich nur in der Lage sein wird, einen Teil davon sein Karte die Datei. Um auf den Rest der Datei zuzugreifen, muss der erste Teil entmapselt und der nächste Teil an seiner Stelle zugeordnet werden.

Da Sie MPEG-Streams entschlüsseln, möchten Sie möglicherweise einen doppelt gepufferten Ansatz mit asynchronem Lesen von Dateien verwenden. Es funktioniert so:

blocksize = 65536 bytes (or whatever) 
currentblock = new byte [blocksize] 
nextblock = new byte [blocksize] 
read currentblock 
while processing 
    asynchronously read nextblock 
    parse currentblock 
    wait for asynchronous read to complete 
    swap nextblock and currentblock 
endwhile