Wie bekomme ich Java, um meinen Multi-Core-Prozessor mit GZIPInputStream zu verwenden?

8

Ich verwende einen GZIPInputStream in meinem Programm, und ich weiß, dass die Leistung verbessert würde, wenn ich Java dazu bringen könnte, mein Programm parallel auszuführen.

Gibt es im Allgemeinen eine Befehlszeilenoption für die Standard-VM, die auf vielen Kernen ausgeführt wird? Es läuft nur auf einem wie es ist.

Danke!

Bearbeiten

Ich laufe einfach auf Java SE 6 Update 17 unter Windows XP.

Würde das Einfügen des GZIPInputStream in einen separaten Thread explizit helfen? Nein! Legen Sie den GZIPInputStream nicht auf einen separaten Thread! Multithread-I / O NICHT!

Bearbeiten 2

Ich nehme an, dass I / O der Engpass ist, da ich auf der gleichen Platte lese und schreibe ...

Im Allgemeinen gibt es jedoch eine Möglichkeit, GZIPInputStream schneller zu machen? Oder ein Ersatz für GZIPInputStream, der parallel läuft?

Bearbeiten 3 Code-Snippet habe ich verwendet:

GZIPInputStream gzip = new GZIPInputStream(new FileInputStream(INPUT_FILENAME)); DataInputStream in = new DataInputStream(new BufferedInputStream(gzip));

    
Rudiger 01.01.2010, 21:08
quelle

8 Antworten

16

AFAIK die Aktion des Lesens aus diesem Stream ist single-threaded, so dass mehrere CPUs Ihnen nicht helfen werden, wenn Sie eine Datei lesen.

Sie könnten jedoch mehrere Threads haben, die jeweils eine andere Datei entpacken.

Da das Entpacken in diesen Tagen nicht besonders rechenintensiv ist, ist es wahrscheinlicher, dass Sie durch die Kosten von IO blockiert werden (zB wenn Sie zwei sehr große Dateien in zwei verschiedenen Bereichen der HD lesen) / p>

Ganz allgemein (vorausgesetzt, es handelt sich um eine neue Java-Person) macht Java die Dinge für Sie nicht parallel. Sie müssen Threads verwenden, um zu sagen, welche Arbeitseinheiten Sie ausführen möchten und wie Sie diese synchronisieren können. Java (mit Hilfe des Betriebssystems) nimmt im Allgemeinen so viele Kerne, wie es ihm zur Verfügung steht, und tauscht auch Threads auf demselben Kern aus, wenn es mehr Threads als Kerne gibt (was typischerweise der Fall ist).

    
Uri 01.01.2010, 21:14
quelle
5

PIGZ = Parallele Implementierung von GZip ist ein voll funktionsfähiger Ersatz für gzip, der beim Komprimieren von Daten mehrere Prozessoren und mehrere Kerne ausnutzt. Ссылка Es ist noch nicht Java - irgendwelche Abnehmer. Natürlich braucht die Welt es in Java.

Manchmal ist die Komprimierung oder Dekomprimierung ein großer CPU-Konsument, obwohl es den I / O nicht hilft, den Engpass zu sein.

Siehe auch Dataseries (C ++) von HP Labs. PIGZ parallelisiert nur die Komprimierung, während Dataseries die Ausgabe in große komprimierte Blöcke aufteilt, die parallel dekomprimierbar sind. Hat auch eine Reihe anderer Funktionen.

    
George 20.01.2010 22:15
quelle
2

Wickeln Sie Ihre GZIP-Streams in gepufferte Streams, dies sollte Ihnen eine deutliche Leistungssteigerung bringen.

%Vor%

Und ebenso für den Eingabestrom. Die Verwendung der gepufferten Eingabe- / Ausgabeströme reduziert die Anzahl der Lesevorgänge auf der Festplatte.

    
Sam Barnum 01.01.2010 21:33
quelle
2

Ich sehe keine Antwort auf die andere Verarbeitung Ihres Programms.

Wenn Sie nur eine Datei entpacken, verwenden Sie einfach die Befehlszeile gunzip tool; aber wahrscheinlich passiert etwas Verarbeitung mit den Dateien, die Sie aus diesem Stream ziehen.

Wenn Sie etwas extrahieren, das in Blöcken von vernünftiger Größe enthalten ist, sollte die Verarbeitung dieser Blöcke in einem separaten Thread vom Entpacken erfolgen.

Sie könnten einen Thread für jeden großen String oder anderen Datenblock manuell starten. aber seit Java 1.6 oder so, wäre es besser mit einer der ausgefallenen neuen Klassen in java.util.concurrent , wie zB ThreadPoolExecutor .

Aktualisieren

Es ist mir aus der Frage und anderen Kommentaren nicht klar, ob Sie wirklich nur Dateien mit Java extrahieren. Wenn Sie wirklich, wirklich denken, dass Sie versuchen sollten, mit gunzip zu konkurrieren, dann können Sie wahrscheinlich etwas Leistung erzielen, indem Sie große Puffer verwenden; h., arbeite mit einem Puffer von beispielsweise 10 MB (binär, nicht dezimal! - 1048576), fülle das in einem einzigen Schluck und schreibe es ebenfalls auf die Platte. Dadurch erhält Ihr Betriebssystem die Möglichkeit, Speicherplatz auf mittlerer Ebene zu planen. Außerdem benötigen Sie weniger Aufrufe auf Systemebene.

    
Carl Smotricz 01.01.2010 21:45
quelle
0

Die Komprimierung scheint ein schwieriger Fall für die Parallelisierung zu sein, da die vom Komprimierer ausgegebenen Bytes eine nicht-triviale Funktion der vorherigen W-Bytes der Eingabe sind, wobei W die Fenstergröße ist. Sie können eine Datei natürlich in Teile zerlegen und unabhängige Komprimierungsströme für jedes Teil erstellen, das in ihren eigenen Threads ausgeführt wird. Möglicherweise müssen Sie einige Komprimierungsmetadaten beibehalten, damit der Dekomprimierer weiß, wie er die Datei wieder zusammenfügt.

    
James K Polk 01.01.2010 21:34
quelle
0

Komprimierung und Dekomprimierung mit gzip ist ein serialisierter Prozess. Um mehrere Threads zu verwenden, müssten Sie ein benutzerdefiniertes Programm erstellen, um die Eingabedatei in viele Streams zu zerlegen, und dann ein benutzerdefiniertes Programm, um sie zu dekomprimieren und wieder zusammenzufügen. So oder so wird IO ein Flaschenhals sein, bevor die CPU genutzt wird.

    
Jarrod Roberson 01.01.2010 21:49
quelle
0

Führen Sie mehrere VMs aus. Jede VM ist ein Prozess und Sie sollten in der Lage sein, mindestens drei Prozesse pro Kern auszuführen, ohne dass die Leistung darunter leidet. Natürlich müsste Ihre Anwendung Multiprocessing nutzen können, um davon zu profitieren. Es gibt kein Wundermittel, weshalb Artikel in der Presse darüber stöhnen, dass wir noch nicht wissen, wie man Multicore-Maschinen einsetzt.

Es gibt jedoch viele Leute, die ihre Anwendungen in einen Master strukturiert haben, der einen Pool von Worker-Prozessen verwaltet und Arbeitspakete an sie verteilt. Nicht alle Probleme sind auf diese Weise lösbar.

    
Michael Dillon 01.01.2010 22:42
quelle
0

Ich denke, es ist ein Fehler anzunehmen, dass Multithreading IO immer böse ist. Sie müssen wahrscheinlich Ihren speziellen Fall profilieren, um sicher zu sein, denn:

  • Neueste Betriebssysteme verwenden den derzeit freien Speicher für den Cache, und Ihre Dateien befinden sich möglicherweise nicht auf der Festplatte, wenn Sie sie lesen.
  • Neue Festplatten wie SSD haben viel schnellere Zugriffszeiten, daher ist das Ändern des Leseorts viel weniger ein Problem.
  • Die Frage ist zu allgemein, um anzunehmen, dass wir von einer einzelnen Festplatte lesen.

Sie müssen möglicherweise Ihren Lesepuffer optimieren, um ihn groß genug zu machen, um die Wechselkosten zu reduzieren. Im Grenzfall kann man alle Dateien im Speicher lesen und dort parallel dekomprimieren - schneller und ohne Verlust beim IO-Multithreading. Etwas weniger Extremes kann jedoch auch besser funktionieren.

Sie müssen auch nichts Besonderes tun, um mehrere verfügbare Cores in JRE zu verwenden. Verschiedene Threads verwenden normalerweise unterschiedliche Kerne, die vom Betriebssystem verwaltet werden.

    
h22 09.02.2013 10:37
quelle