Zstd: La salida multiproceso de Zstd puede depender del número de subprocesos

Creado en 25 sept. 2020  ·  3Comentarios  ·  Fuente: facebook/zstd

Describe el error
Según lo informado por @animalize en el número 2238:

Cuando se utiliza la directiva de finalización ZSTD_e_end y el tamaño del búfer de salida> = ZSTD_compressBound (), el número de trabajo se calcula mediante la función ZSTDMT_computeNbJobs (). Esta función produce un número diferente de trabajos dependiendo de nbWorkers :

https://github.com/facebook/zstd/blob/b706286adbba780006a47ef92df0ad7a785666b6/lib/compress/zstdmt_compress.c#L1243 -L1255

Comportamiento esperado
La salida de la compresión zstd multiproceso debe ser independiente del número de subprocesos.

Reparar

  • [] Haga que ZSTDMT_computeNbJobs() independiente de nbWorkers .
  • [] Agregue una prueba de fuzz que verifique que la salida de zstd multiproceso es siempre independiente del número de subprocesos.

Solución alterna
Si necesita solucionar este error, no inicie su trabajo de transmisión con ZSTD_e_end. Pase al menos un byte de entrada con ZSTD_e_continue antes de llamar a ZSTD_e_end, o asegúrese de que su búfer de salida sea < ZSTD_compressBound(inputSize) .

bug

Comentario más útil

Esto podría ser menos perturbador que intentar adaptar el compresor MT de un solo paso,
que nunca fue diseñado para ofrecer esta garantía.

Sí, probablemente sea más fácil. Había olvidado que todos los trabajos del compresor MT de un solo paso debían iniciarse a la vez.

Una vez quise proponer agregar una función ZSTD_compressStream3 (), que siempre está bloqueando en compresión multiproceso.

En general, la forma en que la gente escribe bucles de compresión de transmisión, no debería ser muy inconveniente no hacer un progreso máximo hacia adelante. Si tuviéramos que agregar algo como esto, no requeriría una nueva API. Probablemente solo necesitemos agregar un parámetro de compresión para controlarlo. Pero, actualmente no veo una gran necesidad para ello.

Todos 3 comentarios

Es un atajo para decir que el resultado de zstd multiproceso no depende de nb de subprocesos.

En realidad, la característica admitida es que el resultado de _streaming_ multiproceso zstd no depende de nb de subprocesos
(y eso es lo que usa el zstd CLI).

Esta definición permite considerar otra posible solución:
no utilice el atajo de una pasada para ZSTD_e_end cuando nbWorkers >= 1 ,
ya que es la delegación al modo de una pasada la que desencadena este problema.

Esto podría ser menos perturbador que intentar adaptar el compresor MT de un solo paso,
que nunca fue diseñado para ofrecer esta garantía.

Otro efecto secundario (potencialmente positivo) es que garantizaría que la transmisión de compresión multiproceso sea _siempre_ sin bloqueo, ya que ya no delegaría en el modo (bloqueo) de un solo paso.
_edit_: elimine eso, ya no delegar al modo de un solo paso no garantiza el no bloqueo, ya que al recibir la directiva ZSTD_e_flush y ZSTD_e_end , el contrato de la API de MT cambia de progreso mínimo hacia adelante a progreso máximo.

Otro efecto secundario (potencialmente positivo) es que garantizaría que la compresión de multiproceso de transmisión siempre sea sin bloqueo, ya que ya no delegaría en el modo de bloqueo.

Una vez quise proponer agregar una función ZSTD_compressStream3() , que siempre está bloqueando en compresión multiproceso.

Si la persona que llama sigue comprobando el progreso sin bloqueo, es muy inconveniente .

editar : Recién encontrado, verificar el progreso no es muy inconveniente:

do {
    zstd_ret = ZSTD_compressStream2(self->cctx, &out, &in, ZSTD_e_continue);
} while (out.pos != out.size && in.pos != in.size && !ZSTD_isError(zstd_ret));

Pero es mejor tener un ZSTD_compressStream3() siempre bloqueando, puede ser un poco más rápido, en mi opinión, muchos usuarios de programadores no necesitan obtener el progreso de la compresión.

Esto podría ser menos perturbador que intentar adaptar el compresor MT de un solo paso,
que nunca fue diseñado para ofrecer esta garantía.

Sí, probablemente sea más fácil. Había olvidado que todos los trabajos del compresor MT de un solo paso debían iniciarse a la vez.

Una vez quise proponer agregar una función ZSTD_compressStream3 (), que siempre está bloqueando en compresión multiproceso.

En general, la forma en que la gente escribe bucles de compresión de transmisión, no debería ser muy inconveniente no hacer un progreso máximo hacia adelante. Si tuviéramos que agregar algo como esto, no requeriría una nueva API. Probablemente solo necesitemos agregar un parámetro de compresión para controlarlo. Pero, actualmente no veo una gran necesidad para ello.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

robert3005 picture robert3005  ·  4Comentarios

sergeevabc picture sergeevabc  ·  3Comentarios

xorgy picture xorgy  ·  3Comentarios

AbdulrahmanAltabba picture AbdulrahmanAltabba  ·  3Comentarios

rgdoliveira picture rgdoliveira  ·  3Comentarios