ThinkMeta LogoDeutsch
English
LAME: Asynchrone Dateiverarbeitung

Der Enkodiervorgang auf Dateiebene in LAME ist in folgender Abbildung dargestellt:

Dateiverarbeitung in LAME

Die unkomprimierte Datei wird blockweise eingelesen und die komprimierte Datei block­weise geschrieben. Hierbei wechseln sich Lese- und Schreiboperationen ab.

Obwohl diese Vorgehensweise und die Verwendung von synchronen I/O-Operationen nicht optimal ist, wird die Geschwindigkeit beim Enkodieren einer einzelnen Datei da­durch nicht beeinträchtigt.

Als Pseudocode lässt sich der Vorgang in einer imperativen Programmiersprache wie folgt beschreiben:

MP3EncodeFile(wavFilename, mp3Filename)
{
  infile = OpenFile(wavFilename);
  outfile = OpenFile(mp3Filename);
  for (i = 0; i < maxBlocks; ++i) {
    inblock = ReadBlock(infile);
    outblock = EncodeBlock(inblock);
    WriteBlock(outfile, outblock);
  }
}

Prinzipiell ist es möglich, die Funktion "MP3EncodeFile" für mehrere Dateien parallel auf verschiedenen Threads auszuführen. Dies eignet sich für zwei bis drei Threads.
Bei noch mehr Threads konkurrieren jedoch zu viele I/O-Operationen parallel um einen seriellen Datenträger, sodass die dadurch entstehenden Effizienzverluste den Nutzen wei­terer Prozessoren übersteigen.

Um solche Probleme behandeln zu können, besitzt Fiber Pool einen I/O-Scheduler. Die­sem kann man eine beliebige Anzahl an Aufträgen geben, die dann mit bestmöglicher I/O- Performance abgearbeitet werden.

Der Pseudocode dazu könnte in einer asynchronen Programmiersprache wie folgt aus­se­hen:

MP3EncodeFile(wavFilename, mp3Filename)
{
  Memory inMemory;
  Memory outMemory;
  ReadFile(wavFilename, inMemory);
  WriteFile(mp3Filename, outMemory);
  Encode(inMemory, outMemory);
}

Beim Aufrufen dieser Funktion werden die drei Aufträge "ReadFile", "WriteFile" und "En­code" dem darunterliegenden System (hier: Fiber Pool) zur Bearbeitung übergeben.

Für die Bearbeitung mehrerer Dateien kann die Funktion beliebig oft aufgerufen werden, sodass bei n Dateien 3n Aufträge an das System übergeben werden.

Im Gegensatz zur imperativen Lösung, in der die Sichtweite eines Threads die aktuell ausgeführte Programmzeile ist und keine Kenntnisse über weitere Threads existieren, erhält das asynchrone System ausreichend Informationen, um Strategien hinsichtlich der Verwendung von CPU, I/O und Speicher bis zum nächsten Synchronisationspunkt entwickeln zu können.

Implementierung in fpMP3:
Die asynchrone Funktion "MP3EncodeFile" wurde als C++-Klasse "MP3EncodingTask" implementiert. Als I/O-Strategie wurde festgelegt, lesende Operationen gegenüber schrei­benden zu bevorzugen (s. auch Dokumentation zu "Set­Default­FileIO­Scheduling­Strategy").
Über die Kommandozeile können CPU- und Speicherverwaltungsstrategie angepasst werden.