Décrivez le bogue
Tel que rapporté par @animalize dans le numéro #2238 :
Lors de l'utilisation de la directive de fin ZSTD_e_end et de la taille du tampon de sortie >= ZSTD_compressBound(), le numéro de tâche est calculé par la fonction ZSTDMT_computeNbJobs(). Cette fonction produit un nombre différent de jobs en fonction de nbWorkers
:
Comportement prévisible
La sortie de la compression multithread zstd doit être indépendante du nombre de threads.
Réparer
ZSTDMT_computeNbJobs()
indépendant de nbWorkers
.solution de contournement
Si vous devez contourner ce bogue, ne démarrez pas votre tâche de streaming avec ZSTD_e_end. Passez au moins un octet d'entrée avec ZSTD_e_continue avant d'appeler ZSTD_e_end, ou assurez-vous que votre tampon de sortie est de < ZSTD_compressBound(inputSize)
.
C'est un raccourci pour dire que le résultat de zstd
multithread ne dépend pas du nb de threads.
En fait, la fonctionnalité prise en charge est que le résultat de _streaming_ multithread zstd
ne dépend pas du nb de threads
(et c'est ce qui est utilisé par la CLI zstd
).
Cette définition permet d'envisager une autre solution potentielle :
n'utilisez pas le raccourci en un seul passage pour ZSTD_e_end
lorsque nbWorkers >= 1
,
puisque c'est la délégation au mode monopasse qui déclenche ce problème.
Cela pourrait être moins perturbant que d'essayer d'adapter le compresseur MT à un seul passage,
qui n'a jamais été conçu pour offrir cette garantie.
Un autre effet secondaire (potentiellement positif) est que cela garantirait que la compression multithread en streaming est _toujours_ non bloquante, car elle ne déléguerait plus au mode (bloquant) à passage unique.
_edit_ : supprimez cela, ne plus déléguer au mode monopasse ne garantit pas le non-blocage, car à la réception des directives ZSTD_e_flush
et ZSTD_e_end
, le contrat de l'API MT passe d'une progression minimale à progression maximale.
Un autre effet secondaire (potentiellement positif) est que cela garantirait que la compression multithread en streaming est toujours non bloquante, car elle ne déléguerait plus au mode de blocage.
J'ai une fois voulu proposer d'ajouter une fonction ZSTD_compressStream3()
, qui bloque toujours en compression multithread.
Si l'appelant continue de vérifier la progression non bloquante, c'est très gênant .
edit : Je viens de trouver, vérifier la progression n'est pas très gênant :
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));
Mais il est préférable d'avoir un ZSTD_compressStream3()
toujours bloquant, cela peut être un peu plus rapide, IMO, de nombreux utilisateurs de programmeurs n'ont pas besoin d'obtenir la progression de la compression.
Cela pourrait être moins perturbant que d'essayer d'adapter le compresseur MT à un seul passage,
qui n'a jamais été conçu pour offrir cette garantie.
Oui, c'est probablement plus facile. J'avais oublié que tous les travaux du compresseur MT à un seul passage devaient être lancés en même temps.
J'ai une fois voulu proposer d'ajouter une fonction ZSTD_compressStream3(), qui bloque toujours en compression multithread.
Généralement, la façon dont les gens écrivent des boucles de compression de streaming, il ne devrait pas être très gênant de ne pas progresser au maximum. Si nous devions ajouter quelque chose comme ça, cela ne nécessiterait pas une nouvelle API. Nous aurions probablement juste besoin d'ajouter un paramètre de compression pour le contrôler. Mais, je n'en vois pas actuellement un grand besoin.
Commentaire le plus utile
Oui, c'est probablement plus facile. J'avais oublié que tous les travaux du compresseur MT à un seul passage devaient être lancés en même temps.
Généralement, la façon dont les gens écrivent des boucles de compression de streaming, il ne devrait pas être très gênant de ne pas progresser au maximum. Si nous devions ajouter quelque chose comme ça, cela ne nécessiterait pas une nouvelle API. Nous aurions probablement juste besoin d'ajouter un paramètre de compression pour le contrôler. Mais, je n'en vois pas actuellement un grand besoin.