Multithreading


Alle Seminare - Inhaltsübersicht - Vorher: Modifikationen und Kombinationen - Nächstes: Praktische Garbage Collectoren

Übersicht: Multithreading


Multithreading

Wenn die Wirtssprache Multithreading unterstützt, muß der Garbage Collector damit klar kommen. Im einfachsten Fall werden einfach alle Threads angehalten bis auf einen, der dann den Durchlauf des Garbage Collectors ausführt.

Die Multithreadfähigkeit kann aber auch aktiv ausgenutzt werden, indem der Durchlauf in einem eigenen Thread mit niedriger Priorität passiert, und so keine extra Zeit oder Pausen für den Garbage Collector benötigt wird. Dadurch kann zumindest die Anzahl der Pausen reduziert werden, so daß nur bei besonders großen Speicheranforderungen noch eine Bereinigung mit Wartezeiten im Anwenderprogramm notwendig ist. Je nach Algorithmus erfolgt der Durchlauf entweder komplett parallel oder nur einige der Phasen. Die letzten Phasen werden in dem Fall dann durchgeführt, während das Anwederprogramm gestoppt ist, da dabei nur ein Teil der Arbeit durchgeführt wird, ist die Pausezeit immer noch deutlich geringer. Um einen Durchlauf durchzuführen während das Anwenderprogramm läuft, muß natürlich eine Synchronisation zwischen dem Anwenderprogramm und dem Garbage Collector durchgeführt werden. Auch alle Änderungen an Referenzen in bereits geprüften Objekten müssen an den Garbage Collector übermittelt werden. Dieser Zusatzaufwand verringert natürlich die Effizienz insgesamt wieder, daher ist der parallele Durchlauf des Garbage Collectors meist nur nützlich, wenn dies mit Hardwareunterstützung geschieht.

Kurve über sinkende Effizienz für jeden weiteren Prozessor
Diese Kurve s(n) = 1 / (β + (1 - β) / n) wurde nach Amdahls Gesetz angefertigt, wobei von einem Anteil von β = 10% für die nur seriell ausführbare Arbeit ausgegangen wurde. Die Anzahl der Prozessoren n ist auf der X-Achse eingetragen, die entsprechende Leistungsfähigkeit auf der Y-Achse. Als theoretischer Wert wird floor(n) zum Vergleich ebenfalls angezeigt.
Man sieht, daß beim Hinzufügen eines weiteren Prozessors die Gesamtleistungsfähigkeit nicht proportional steigt, die Gesamteffizienz sinkt also. Bei jedem weiteren Prozessoren steigt die Leistung um einen immer geringeren Wert.

Sobald ein Mehrprozessorsystem genutzt wird, muß der Garbage Collector zumindest unterstützen, seinen Durchlauf auf entsprechend viele Threads aufzuteilen, selbst wenn er nicht parallel zum Anwenderprogramm laufen kann. Je nach verwendeten Algorithmus kann dies durchaus komplizierter sein. Beispielsweise kann ein und die selbe Speicherstelle verschiedene Werte (Referenzen) enthalten auf verschiedenen Prozessoren und damit Threads durch internes Puffern.

Threadlokaler Speicher

Da beim Anfordern von Speicher jedesmal der Thread einen geschützen Bereich (kritischer Abschnitt) betreten muß, der nur von einem Thread zu Zeit bearbeitet werden kann, kann hier ein Flaschenhals entstehen und die Skalierbarkeit durchbrochen werden. Um dies zu verhindern sollte jeder Thread sich einen eigenen gechützten Speicherbereich besorgen, auf den dieser dann ohne vorherige Synchronisation jederzeit Speicher anfordern kann. Bei generationellen Garbage Collectoren ist dies eine einfache Erweiterung, daß die jüngste Generation immer in diesen Threadlokalen Speicherbereichen angelegt wird. Während des Garbage Collector Durchlaufs kann so jeder Thread auch einfach seinen eigenen Speicherbereich scannen.


Alle Seminare - Inhaltsübersicht - Vorher: Modifikationen und Kombinationen - Nächstes: Praktische Garbage Collectoren Seitenanfang