2009-07-31 7 views
6

Esiste una libreria in .net che esegue la compressione multithread di uno stream? Sto pensando a qualcosa come il costruito in System.IO.GZipStream, ma usando più thread per eseguire il lavoro (e quindi utilizzando tutti i core della CPU).Compressione multithread in C#

So che, ad esempio, comprime 7-zip utilizzando più thread, ma il C# SDK che hanno rilasciato non sembra farlo.

risposta

7

Penso che la soluzione migliore sia dividere il flusso di dati a intervalli uguali e avviare thread per comprimere ogni parte separatamente in parallelo, se si utilizzano algoritmi non parallelizzati. (Dopo di che un singolo thread li concatena in un singolo stream (è possibile creare una classe di stream che continua a leggere dal flusso successivo quando termina quello corrente)).

Si potrebbe dare un'occhiata a SharpZipLib che è un po 'meglio dei flussi di compressione intrinseca in .NET.

MODIFICA: occorrerà un'intestazione per indicare dove inizia ogni nuovo flusso, naturalmente. :)

+0

Sì, sono d'accordo, non riesco a pensare a librerie di compressione specificamente parallele. Se qualcuno doveva scriverne uno, non posso pensare a come funzionerebbe se non suddividendo i dati grezzi in blocchi e comprimendoli ciascuno su un thread. Tieni presente che se lo dividi in parti troppo piccole ridurrai l'efficienza della compressione (sia in termini di tempo che di dimensioni). –

+0

Una buona menzione di SharpZipLib, in realtà sto già usando. Per quanto riguarda la suddivisione del flusso, sì, sono a conoscenza di tale soluzione, sfortunatamente, il requisito è quello di comprimere un singolo flusso che viene alimentato al mio codice e di scrivere su un singolo flusso compresso, in modo che i dati in ingresso non siano realmente frammentati un opzione. – Gareth

+1

Sembra che tu stia cercando una filettatura molto fine, o "micro-parallelizzazione", se ti va. Se hai il tempo potresti trovare un modo per modificare le subroutine di #ZipLib per usare loop paralleli, come quelli che si trovano in Parallel.NET (o come si chiama). –

0

Un formato di compressione (ma non necessariamente l'algoritmo) deve essere consapevole del fatto che è possibile utilizzare più thread. O meglio, non necessariamente che usi più thread, ma che stai comprimendo i dati originali in più passaggi, parallelamente o in altro modo.

Lasciatemi spiegare.

La maggior parte degli algoritmi di compressione comprime i dati in modo sequenziale. Qualsiasi dato può essere compresso utilizzando le informazioni apprese da dati già compressi. Ad esempio, se stai comprimendo un libro da un autore errato, che usa più parole, cliché e frasi più volte, nel momento in cui l'algoritmo di compressione arriva al secondo + occorrenza di quelle cose, di solito sarà in grado di comprimere l'occorrenza corrente meglio della prima occorrenza.

Tuttavia, un effetto collaterale di ciò è che non è possibile unire realmente due file compressi senza decomprimerli entrambi e ricomprimerli come un unico flusso. La conoscenza di un file non corrisponderebbe all'altro file.

La soluzione, naturalmente, è di dire alla routine di decompressione che "Ehi, ho appena passato a un flusso di dati completamente nuovo, per favore inizia a costruire nuove conoscenze sui dati".

Se il formato di compressione supporta tale codice, è possibile comprimere facilmente più parti contemporaneamente.

Ad esempio, un file da 1 GB può essere diviso in 4 file da 256 MB, comprimere ciascuna parte su un core separato e quindi unire insieme alla fine.

Se si sta costruendo il proprio formato di compressione, è ovviamente possibile creare il supporto da soli.

Se il formato .ZIP o .RAR o uno qualsiasi dei formati di compressione noti può supportare ciò non mi è noto, ma so che il formato .7Z può.

4

Trovato questa libreria: http://www.codeplex.com/sevenzipsharp

sembra che avvolge il 7z.dll non gestito che supporta il multithreading. Ovviamente non è il caso di dover avvolgere codice non gestito, ma sembra che questa sia attualmente l'unica opzione disponibile.

-1

In genere, direi provare Intel Parallel Studio, che consente di sviluppare codice specificamente mirato ai sistemi multi-core, ma per ora utilizza solo C/C++. Magari creare solo lib in C/C++ e chiamarlo dal tuo codice C#?

+0

Non vedo come questo possa essere d'aiuto. Se sta chiamando una libreria di compressione che non è multi-thread, chiamarla da una libreria C++ che è stata scritta con Intel Parallel Studio non la renderà multi-threaded. È? (Forse lo è, non l'ho mai usato) –

4

Recentemente ho trovato una libreria di compressione che supporta la compressione bzip multithread: DotNetZip. La cosa bella di questa libreria è che la classe ParallelBZip2OutputStream è derivata da System.IO.Stream e prende come output un System.IO.Stream. Ciò significa che è possibile creare una catena di classi derivate da System.IO.Stream come:

  • ICSharpCode.SharpZipLib.Tar.TarOutputStream
  • Ionic.BZip2.ParallelBZip2OutputStream (dalla biblioteca DotNetZip)
  • di sistema .Security.Cryptography.CryptoStream (per la crittografia)
  • System.IO.FileStream

In questo caso creiamo un file .tar.bz, cifrare (magari con AES) e scrivere direttamente in un file .