2009-07-31 12 views
6

Gibt es eine Bibliothek in .net, die Multithread-Komprimierung eines Streams durchführt? Ich denke an etwas wie das eingebaute System.IO.GZipStream, aber die Verwendung mehrerer Threads, um die Arbeit auszuführen (und dabei alle CPU-Kerne zu verwenden).Multithread-Komprimierung in C#

Ich weiß, dass zum Beispiel 7-Zip-Komprimierungen mit mehreren Threads, aber die C# SDK, die sie veröffentlicht haben, scheint das nicht zu tun.

Antwort

7

Ich denke, Ihre beste Wette ist, den Datenstrom selbst in gleichen Intervallen zu teilen und Threads zu starten, um jedes Teil einzeln parallel zu komprimieren, wenn Sie nicht-parallelisierte Algorithmen verwenden. (Nach dem ein einzelner Thread sie zu einem einzigen Stream verkettet (Sie können eine Stream-Klasse erstellen, die fortfährt, aus dem nächsten Stream zu lesen, wenn der aktuelle endet)).

Vielleicht möchten Sie einen Blick auf SharpZipLib werfen, die etwas besser ist als die intrinsischen Komprimierungsströme in .NET.

BEARBEITEN: Sie benötigen natürlich eine Kopfzeile, um zu sagen, wo jeder neue Stream beginnt. :)

+0

Ja, ich stimme dem zu, ich kann mir keine spezifisch parallelen Komprimierungsbibliotheken vorstellen. Wenn jemand eines schreiben würde, kann ich nicht denken, wie es funktionieren würde, abgesehen davon, dass die Rohdaten in Stücke aufgeteilt und jeweils auf einem Thread komprimiert werden. Beachten Sie, dass Sie die Effizienz der Komprimierung (sowohl Zeit als auch Größe) verringern, wenn Sie sie in zu kleine Teile aufteilen. –

+0

Gute Erwähnung von SharpZipLib, ich benutze es eigentlich schon. Bezüglich der Aufteilung des Streams, ja, ich bin mir dieser Lösung bewusst, leider ist die Anforderung, einen einzigen Stream zu komprimieren, der in meinen Code eingespeist wird, und in einen einzelnen komprimierten Stream zu schreiben, so dass das Chunking der eingehenden Daten nicht wirklich ist eine Option. – Gareth

+1

Scheint, als ob Sie nach sehr feinkörnigem Threading oder "Mikro-Parallelisierung" suchen, wenn Sie möchten. Wenn Sie Zeit haben, finden Sie möglicherweise eine Möglichkeit, Subroutinen von #ZipLib zu modifizieren, um parallelisierte Schleifen zu verwenden, wie sie in Parallel.NET (oder wie auch immer es genannt wird) zu finden sind. –

0

Ein Komprimierungsformat (aber nicht unbedingt der Algorithmus) muss sich der Tatsache bewusst sein, dass Sie mehrere Threads verwenden können. Oder, nicht unbedingt, dass Sie mehrere Threads verwenden, sondern dass Sie die ursprünglichen Daten in mehreren Schritten parallel oder anderweitig komprimieren.

Lassen Sie mich erklären.

Die meisten Komprimierungsalgorithmen komprimieren Daten sequenziell. Alle Daten können komprimiert werden, indem Informationen verwendet werden, die von bereits komprimierten Daten gelernt wurden. Wenn Sie zum Beispiel ein Buch von einem schlechten Autor komprimieren, der viele gleiche Wörter, Klischees und Sätze mehrfach verwendet, wird der Komprimierungsalgorithmus in der Regel zu dem Zeitpunkt sein, zu dem der Komprimierungsalgorithmus zum zweiten + Vorkommen kommt in der Lage, das aktuelle Vorkommen besser zu komprimieren als das erste Vorkommen.

Ein Nebeneffekt davon ist jedoch, dass Sie nicht wirklich zwei komprimierte Dateien zusammenfügen können, ohne beides zu dekomprimieren und sie als einen Stream neu zu komprimieren. Das Wissen aus einer Datei würde nicht mit der anderen Datei übereinstimmen.

Die Lösung ist natürlich, der Dekompressionsroutine zu sagen: "Hey, ich bin gerade auf einen völlig neuen Datenstrom umgestiegen, bitte fange an, neues Wissen über die Daten aufzubauen".

Wenn das Komprimierungsformat einen solchen Code unterstützt, können Sie mehrere Komponenten gleichzeitig problemlos komprimieren.

Zum Beispiel könnte eine 1GB-Datei in 4 256MB-Dateien aufgeteilt werden, jeden Teil auf einem separaten Kern komprimieren und dann am Ende zusammenfügen.

Wenn Sie Ihr eigenes Komprimierungsformat erstellen, können Sie natürlich selbst Unterstützung dafür erstellen.

Ob .ZIP oder .RAR oder eines der bekannten Komprimierungsformate können dies unterstützen, ist mir unbekannt, aber ich kenne das .7Z-Format kann.

4

diese Bibliothek gefunden: http://www.codeplex.com/sevenzipsharp

Sieht aus wie es die nicht verwaltete 7z.dll wickelt, die Multithreading unterstützt. Natürlich ist es nicht ideal, unmanaged Code einzubinden, aber es sieht so aus, als ob dies momentan die einzige Option ist, die es gibt.

-1

Normalerweise würde ich sagen, versuchen Sie Intel Parallel Studio, mit dem Sie Code speziell für Multi-Core-Systeme entwickelt, aber für jetzt ist es nur C/C++. Vielleicht einfach lib in C/C++ erstellen und das von Ihrem C# -Code aus aufrufen?

+0

Ich sehe nicht, wie das helfen würde. Wenn er eine Komprimierungsbibliothek aufruft, die kein Multi-Threading ist, wird der Aufruf aus einer C++ - Bibliothek, die mit Intel Parallel Studio geschrieben wurde, nicht zu einem Multi-Threading führen. Ist es? (Vielleicht ist es, ich habe es nie benutzt) –

4

Ich habe kürzlich eine Komprimierungsbibliothek gefunden, die Multithread-bzip-Komprimierung unterstützt: DotNetZip. Das Schöne an dieser Bibliothek ist, dass die ParallelBZip2OutputStream-Klasse von System.IO.Stream abgeleitet ist und einen System.IO.Stream als Ausgabe akzeptiert. Dies bedeutet, dass Sie eine Kette von Klassen von System.IO.Stream wie abgeleitet erstellen:

  • ICSharpCode.SharpZipLib.Tar.TarOutputStream
  • Ionic.BZip2.ParallelBZip2OutputStream (von der DotNetZip Bibliothek)
  • -System .Security.Cryptography.CryptoStream (zur Verschlüsselung)
  • System.IO.FileStream

In diesem Fall haben wir eine .tar.bz Datei zu erstellen, verschlüsseln (vielleicht mit AES) und direkt in eine Datei schreiben .