LAME: Asynchrone Frame-Verarbeitung
Unkomprimierte Frames durchlaufen während des Enkodiervorgangs mehrere Stufen, die in folgender
Abbildung dargestellt sind:
Die Bearbeitung eines Frames hängt von den Ergebnissen seines Vorgängers ab.
Der Pseudocode (imperativ) dazu ist wie folgt:
MP3EncodeFrames(frames)
{
frames[0] = InitializeFirstFrame();
for (f = 1; f < frames.count; ++f) {
SampleConverter(frames[f], frames[f - 1]);
ReplayGain(frames[f], frames[f - 1]);
PsychoAcoustics(frames[f], frames[f - 1]);
MDCT(frames[f], frames[f - 1]);
Quantizer(frames[f], frames[f - 1]);
BitStream(frames[f], frames[f - 1]);
}
}
Die Suche nach parallelisierbaren Elementen in diesem Code ist kaum sinnvoll, weil ein Frame
auf aktuellen Prozessoren in weniger als 1 ms bearbeitet wird.
Auch die Schleife kann wegen den Abhängigkeiten nicht parallelisiert werden.
Anders sieht es bei Verwendung einer asynchronen Programmiersprache aus: In diesem
Fall kann die Funktion "MP3EncodeFrames" auf eine Weise beschrieben werden, die
ein Parallelisierungspotenzial erkennen lässt – selbst wenn letztendlich keine Parallelisierung
möglich ist:
MP3EncodeFrames(frames)
{
frames[0] = InitializeFirstFrame();
SampleConverter(frames);
ReplayGain(frames);
PsychoAcoustics(frames);
MDCT(frames);
Quantizer(frames);
BitStream(frames);
}
Und repräsentativ für alle asynchronen Aufträge:
SampleConverter(frames)
{
for (f = 1; f < frames.count; ++f)
SampleConverter(frames[f], frames[f - 1]);
}
Die Verarbeitungszeiten der einzelnen Aufträge liegen im Sekundenbereich, sodass hier eine
mögliche Parallelisierung zu einer spürbaren Performancesteigerung führen kann.
Implementierung in fpMP3:
"MP3EncodeFrames" wurde als C++-Klasse "LAMEEncoder" implementiert. Teile der Funktion wurden aus
organisatorischen Gründen in die Klasse "MP3EncodingTask" verlagert.
|