2009-07-31 30 views
6

¿Existe una biblioteca en .NET que realice compresión multiproceso de una secuencia? Estoy pensando en algo así como el construido en System.IO.GZipStream, pero usando múltiples hilos para realizar el trabajo (y de ese modo utilizar todos los núcleos de la CPU).Compresión multiproceso en C#

Sé que, por ejemplo, comprime 7-zip usando varios hilos, pero el SDK C# que han lanzado no parece hacer eso.

Respuesta

7

Creo que su mejor opción es dividir el flujo de datos a intervalos iguales usted mismo, y lanzar hilos para comprimir cada parte por separado en paralelo, si se utilizan algoritmos no paralelizados. (Después de lo cual, un solo hilo los concatena en una sola secuencia (puede hacer una clase de flujo que continúe leyendo desde la siguiente secuencia cuando finalice la actual)).

Es posible que desee echar un vistazo a SharpZipLib que es algo mejor que las secuencias de compresión intrínseca en .NET.

EDITAR: Necesitará un encabezado para indicar dónde comienza cada nueva emisión, por supuesto. :)

+0

Sí, estoy de acuerdo con esto, no puedo pensar en ninguna biblioteca de compresión específicamente paralela. Si alguien escribiera uno, no puedo pensar cómo funcionaría aparte de dividir los datos sin procesar en fragmentos y comprimirlos en un hilo. Tenga en cuenta que si lo divide en trozos demasiado pequeños, reducirá la eficacia de la compresión (tanto en tiempo como en tamaño). –

+0

Buena mención de SharpZipLib, en realidad ya lo estoy usando. Con respecto a la división de la transmisión, sí, estoy al tanto de esa solución. Desafortunadamente, el requisito es comprimir una única transmisión que se transfiera a mi código y escribir en una sola transmisión comprimida, por lo que dividir los datos entrantes no es realmente cierto. una opción. – Gareth

+1

Parece que está buscando un enhebrado de grano muy fino o "micro-paralelización" si lo desea. Si tiene tiempo, puede encontrar una forma de modificar las subrutinas de #ZipLib para usar bucles paralelizados, como los que se encuentran en Parallel.NET (o como se llame). –

0

Un formato de compresión (pero no necesariamente el algoritmo) debe ser consciente del hecho de que puede usar varios hilos. O mejor dicho, no necesariamente que uses múltiples hilos, sino que estás comprimiendo los datos originales en múltiples pasos, en paralelo o de otra forma.

Déjame explicarte.

La mayoría de los algoritmos de compresión comprimen los datos de forma secuencial. Cualquier información puede ser comprimida usando información aprendida de datos ya comprimidos. Entonces, por ejemplo, si está comprimiendo un libro de un autor malo, que usa muchas de las mismas palabras, clichés y oraciones varias veces, cuando el algoritmo de compresión llega a la segunda ocurrencia de esas cosas, generalmente será capaz de comprimir la ocurrencia actual mejor que la primera ocurrencia.

Sin embargo, un efecto secundario de esto es que no se pueden unir realmente dos archivos comprimidos sin descomprimirlos y volver a comprimirlos como una secuencia. El conocimiento de un archivo no coincidiría con el otro archivo.

La solución, por supuesto, es decirle a la rutina de descompresión que "Hola, acabo de cambiar a un flujo de datos totalmente nuevo, por favor comience a acumular nuevos conocimientos sobre los datos".

Si el formato de compresión es compatible con dicho código, puede comprimir fácilmente varias partes al mismo tiempo.

Por ejemplo, un archivo de 1GB podría dividirse en 4 archivos de 256MB, comprimir cada parte en un núcleo separado y luego unirlas al final.

Si está construyendo su propio formato de compresión, puede, por supuesto, generar soporte para esto usted mismo.

No se sabe si .ZIP o .RAR o cualquiera de los formatos de compresión conocidos pueden soportar esto, pero sé que el formato .7Z puede.

4

Encontrado esta biblioteca: http://www.codeplex.com/sevenzipsharp

parece que envuelve el 7z.dll no administrado, que es compatible con múltiples hilos. Obviamente no es ideal tener que ajustar el código no administrado, pero parece que esta es actualmente la única opción disponible.

-1

Normalmente, diría que intente con Intel Parallel studio, que le permite desarrollar código específicamente dirigido a sistemas multi-core, pero por ahora solo lo hace con C/C++. ¿Tal vez crear solo lib en C/C++ y llamarlo desde su código de C#?

+0

No veo cómo esto podría ayudar. Si está llamando a una biblioteca de compresión que no tiene múltiples subprocesos, invocarlo desde una biblioteca en C++ que se escribió con Intel Parallel Studio no lo va a hacer en varios subprocesos. ¿Lo es? (Tal vez lo sea, nunca lo he usado) –

4

Recientemente encontré una biblioteca de compresión que admite la compresión multiproceso bzip: DotNetZip. Lo bueno de esta biblioteca es que la clase ParallelBZip2OutputStream se deriva de System.IO.Stream y toma un System.IO.Stream como salida. Esto significa que se puede crear una cadena de clases derivadas de System.IO.Stream como:

  • ICSharpCode.SharpZipLib.Tar.TarOutputStream
  • Ionic.BZip2.ParallelBZip2OutputStream (de la biblioteca DotNetZip)
  • Sistema .Security.Cryptography.CryptoStream (para el cifrado)
  • System.IO.FileStream

En este caso creamos un archivo .tar.bz, cifrarlo (tal vez con AES) y escribirlos directamente a un archivo .