2009-07-31 17 views
6

Czy istnieje biblioteka w .NET, która kompresuje strumienie wielowątkowe? Myślę o czymś takim, jak wbudowany w System.IO.GZipStream, ale za pomocą wielu wątków, aby wykonać pracę (i tym samym wykorzystując wszystkie rdzenie procesora).Kompresja wielowątkowa w C#

Wiem, że na przykład 7-zip kompresuje za pomocą wielu wątków, ale wydany przez nią C# SDK nie wydaje się tego robić.

Odpowiedz

7

Myślę, że najlepiej jest dzielić strumień danych w równych odstępach czasu i uruchamiać wątki, aby skompresować każdą część osobno równolegle, jeśli używasz nierównoległych algorytmów. (Po którym pojedynczy wątek łączy je w jeden strumień (możesz utworzyć klasę strumienia, która kontynuuje czytanie z następnego strumienia po zakończeniu bieżącego)).

Być może zechcesz rzucić okiem na SharpZipLib, który jest nieco lepszy niż wewnętrzne strumienie kompresji w .NET.

EDYCJA: Będziesz potrzebował nagłówka, aby powiedzieć, gdzie zaczyna się każdy nowy strumień. :)

+0

Tak, zgadzam się z tym, nie mogę wymyślić żadnych specjalnie równoległych bibliotek kompresji. Jeśli ktoś miałby go napisać, nie mogę myśleć, jak by to działało, gdyby nie podzielić surowych danych na porcje i kompresować je w wątku. Pamiętaj, że jeśli podzielisz go na zbyt małe kawałki, zmniejszysz wydajność kompresji (zarówno czasu, jak i rozmiaru). –

+0

Dobra wzmianka o SharpZipLib, właściwie już go używam. Jeśli chodzi o dzielenie strumienia, tak, jestem świadomy tego rozwiązania, niestety wymaganie to skompresowanie pojedynczego strumienia, który jest podawany do mojego kodu i zapisanie do pojedynczego skompresowanego strumienia, więc dzielenie przychodzących danych nie jest tak naprawdę opcja. – Gareth

+1

Wygląda na to, że szukasz bardzo drobnoziarnistego gwintowania lub "mikro-równoległości", jeśli chcesz. Jeśli masz czas, możesz znaleźć sposób modyfikacji podprogramów #ZipLib w celu użycia równoległych pętli, takich jak te znalezione w Parallel.NET (lub jakkolwiek to się nazywa). –

0

Format kompresji (ale niekoniecznie algorytm) musi być świadomy faktu, że można użyć wielu wątków. Lub raczej, niekoniecznie, że używasz wielu wątków, ale kompresujesz oryginalne dane w wielu krokach, równolegle lub w inny sposób.

Pozwól mi wyjaśnić.

Większość algorytmów kompresji kompresuje dane w sposób sekwencyjny. Wszelkie dane można skompresować, korzystając z informacji uzyskanych z już skompresowanych danych. Na przykład, jeśli kompresujesz książkę przez złego autora, który wiele razy używa tych samych słów, stereotypów i zdań, zanim algorytm kompresji przejdzie do drugiego wystąpienia tych rzeczy, zwykle będzie w stanie skompresować obecne wystąpienie lepiej niż pierwsze wystąpienie.

Jednak efektem ubocznym tego jest to, że nie można naprawdę połączyć ze sobą dwóch skompresowanych plików bez ich dekompresji i ponownej kompresji w postaci jednego strumienia. Wiedza z jednego pliku nie pasuje do drugiego pliku.

Rozwiązaniem jest oczywiście wyjaśnienie procedury dekompresji: "Hej, właśnie przełączyłem się na zupełnie nowy strumień danych, zacznij od nowa, budując wiedzę o danych".

Jeśli format kompresji obsługuje taki kod, można z łatwością skompresować wiele części jednocześnie.

Na przykład plik 1GB można podzielić na 4 pliki 256 MB, skompresować każdą część na oddzielnym rdzeniu, a następnie połączyć je na końcu.

Jeśli tworzysz własny format kompresji, możesz oczywiście samodzielnie uzyskać wsparcie.

Bez względu na to, czy funkcja .ZIP, czy .RAR lub którykolwiek ze znanych formatów kompresji obsługuje ten problem, jest mi nieznany, ale wiem, że format .7Z może.

4

Znaleziony tej biblioteki: http://www.codeplex.com/sevenzipsharp

Wygląda na to, że owija niezarządzanej 7z.dll która nie wspiera wielowątkowość. Oczywiście nie jest to idealna konieczność pakowania niezarządzanego kodu, ale wygląda na to, że jest to obecnie jedyna dostępna opcja.

-1

Zwykle chciałbym wypróbować program Intel Parallel Studio, który umożliwia tworzenie kodu specjalnie ukierunkowanego na systemy wielordzeniowe, ale na razie działa tylko w C/C++. Może utworzyć tylko lib w C/C++ i wywołać to z kodu C#?

+0

Nie widzę, jak to mogłoby pomóc. Jeśli wywołuje bibliotekę kompresji, która nie jest wielowątkowa, wywoływanie jej z biblioteki C++, która została napisana w środowisku Intel Parallel Studio, nie sprawi, że będzie ona wielowątkowa. Czy to jest? (Być może tak jest, nigdy go nie używałem) –

4

Ostatnio znalazłem bibliotekę kompresji obsługującą wielowątkową kompresję bzip: DotNetZip. Zaletą tej biblioteki jest to, że klasa ParallelBZip2OutputStream wywodzi się z System.IO.Stream i bierze jako wyjście System.IO.Stream. Oznacza to, że można stworzyć łańcuch klas pochodnych od System.IO.Stream jak:

  • ICSharpCode.SharpZipLib.Tar.TarOutputStream
  • Ionic.BZip2.ParallelBZip2OutputStream (z biblioteki DotNetZip)
  • systemowe .Security.Cryptography.CryptoStream (szyfrowania)
  • System.IO.FileStream

W tym przypadku tworzymy .tar.bz plik, szyfruje je (może z AES) i bezpośrednio zapisać go do pliku .