Force Majeure
Multi-Core-CPUs sind mittlerweile allgegenwärtig. Allerdings kann nicht jede Software ihre gesamte Rechenkraft für sich nutzen.
- Michael Riepe
Kaum ein PC, der heute über den Ladentisch geht, besitzt noch einen Prozessor mit einem einzigen Kern. Sogar Laptops sind oft mit Dual-Core-CPUs ausgestattet. High-End-PCs können mit vier Rechenwerken aufwarten, eventuell außerdem mit Hyperthreading. CPUs mit sechs oder mehr Kernen sind bereits in Sicht; zunächst für Server, später jedoch auch für Desktop-Rechner.
Trotzdem soviel geballter Rechenleistung sitzt der durchschnittliche Anwender oft vor dem Bildschirm und wartet darauf, dass der PC sein Werk verrichtet. Manche Aufgaben lassen sich auch mit vielen Kernen nicht schneller bewältigen – etwa solche, die viele Plattenzugriffe erfordern. Andere hingegen ließen sich in einem Bruchteil der Zeit erledigen, wenn die genutzte Software es verstünde, die Fähigkeiten des Prozessors voll auszureizen.
Das Komprimieren großer Dateien etwa nimmt relativ viel Zeit in Anspruch. Kompressionsalgorithmen weisen in der Regel ein asymmetrisches Laufzeitverhalten auf: Auspacken geht schnell, Einpacken dauert länger. Das trifft vor allem auf moderne Verfahren wie die bei bzip2 verwendete Burrows-Wheeler-Transformation (BWT) oder den LZMA-Algorithmus zu [1].
Päckchen packen im Akkord
Von beiden gibt es parallel arbeitende Varianten. pbzip2 etwa zerlegt seine Eingabedatei in mehrere Stücke und komprimiert diese unabhängig voneinander mit dem BZIP2-Algorithmus. Dabei greift das Programm auf die Bibliothek libbz2 zurück, die die Kernroutinen von bzip2 enthält. Zum Auspacken kann man bzip2 verwenden, allerdings geht es mit pbzip2 schneller. Mit –p <threads> kann der Nutzer dem Programm mitteilen, wie viele Threads es verwenden soll; lässt er die Option weg, versucht es, die Zahl selbst zu ermitteln. Dabei zählt es auch virtuelle CPUs mit.
Ein Mini-Benchmark zeigt, dass die Zeitersparnis erheblich sein kann. Auf einem Linux-PC mit Intels Core i7-860 benötigte pbzip2 zum Einpacken eines 3,5 GByte großen DVD-Image mit acht Threads etwa 3,5 Minuten, während bzip2 mit derselben Aufgabe 16,5 Minuten lang beschäftigt war. Mit mpibzip2 existiert auch eine Version für Cluster, die Gebrauch vom Message Passing Interface (MPI) macht.
Wer den LZMA-Algorithmus bevorzugt, findet in plzip das parallel arbeitende Gegenstück zu lzip. Macht der Nutzer mit der Option –n <threads> keine anderen Vorgaben, startet es ebenfalls einen Thread pro (virtueller) CPU. Unter gleichen Bedingungen – vier Kerne plus Hyperthreading, acht parallele Threads – fällt der Tempozuwachs mit Faktor 5,3 etwa gleich hoch aus wie bei pbzip2 – allerdings nur beim Einpacken. Da das LZMA-Verfahren langsamer arbeitet, ist der reale Zeitgewinn jedoch erheblich höher: Während lzip eine knappe Dreiviertelstunde rechnet, ist plzip schon nach gut 8 Minuten fertig.
Lässt sich eine Aufgabe in voneinander unabhängige Teile zerlegen, benötigt man keine speziell angepasste Software. Wer etwa mehrere Dateien mit gzip komprimieren will, kann die dafür nötigen Befehle mit & im Hintergrund starten und parallel laufen lassen:
for f in <dateien>; do gzip $f & done; wait
Das abschlieĂźende wait blockiert die Shell, bis die Hintergrundprozesse mit der Arbeit fertig sind.
Allerdings hängt die Zahl der parallel laufenden Prozesse von der der Dateien ab. Will man sie begrenzen, muss man auf einen Job Scheduler wie xjobs zurückgreifen. Das Programm liest Befehle von der Standardeingabe oder aus einer Datei und führt sie parallel aus, so schnell es die vorhandenen Ressourcen erlauben. Teile eines Befehls lassen sich als Argumente ans Programm übergeben. Die Zahl der gleichzeitig auszuführenden Jobs kann der Nutzer mit –j <jobs> vorgeben. Obige for-Schleife lässt sich damit einfacher schreiben:
ls <dateien> | xjobs gzip
Einen ähnlichen Ansatz verfolgt jobqueue. Im Gegensatz zu xjobs kann das Programm jedoch fehlgeschlagene Jobs neu starten und die Arbeit auf mehrere Rechner verteilen. Dabei lässt sich sowohl die Gesamtzahl der gleichzeitig laufenden Jobs als auch die Zahl der Jobs pro Rechner festlegen.
Literatur
[1] Michael Riepe; Tools und Tipps; Byte-Quetscher; Daten komprimieren mit dem LZMA-Verfahren; iX 6/2009, S. 131