Zstd: Zstd 닀쀑 μŠ€λ ˆλ“œ 좜λ ₯은 μŠ€λ ˆλ“œ μˆ˜μ— 따라 λ‹¬λΌμ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

에 λ§Œλ“  2020λ…„ 09μ›” 25일  Β·  3μ½”λ©˜νŠΈ  Β·  좜처: facebook/zstd

버그 μ„€λͺ…
문제 #2238μ—μ„œ @animalize κ°€ λ³΄κ³ ν•œ

ZSTD_e_end end μ§€μ‹œλ¬Έκ³Ό 좜λ ₯ 버퍼 크기 >= ZSTD_compressBound()λ₯Ό μ‚¬μš©ν•  λ•Œ μž‘μ—… λ²ˆν˜ΈλŠ” ZSTDMT_computeNbJobs() ν•¨μˆ˜μ— μ˜ν•΄ κ³„μ‚°λ©λ‹ˆλ‹€. 이 ν•¨μˆ˜λŠ” nbWorkers 에 따라 λ‹€λ₯Έ 수의 μž‘μ—…μ„ μƒμ„±ν•©λ‹ˆλ‹€.

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

μ˜ˆμƒλ˜λŠ” 행동
zstd 닀쀑 μŠ€λ ˆλ“œ μ••μΆ•μ˜ 좜λ ₯은 μŠ€λ ˆλ“œ μˆ˜μ™€ 무관해야 ν•©λ‹ˆλ‹€.

κ³ μΉ˜λ‹€

  • [ ] ZSTDMT_computeNbJobs() λ₯Ό nbWorkers λ…λ¦½μ μœΌλ‘œ λ§Œλ“­λ‹ˆλ‹€.
  • [ ] 닀쀑 μŠ€λ ˆλ“œ zstd의 좜λ ₯이 항상 μŠ€λ ˆλ“œ μˆ˜μ™€ 독립적인지 ν™•μΈν•˜λŠ” 퍼지 ν…ŒμŠ€νŠΈλ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.

ν•΄κ²° 방법
이 버그λ₯Ό ν•΄κ²°ν•΄μ•Ό ν•˜λŠ” 경우 ZSTD_e_end둜 슀트리밍 μž‘μ—…μ„ μ‹œμž‘ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€. ZSTD_e_endλ₯Ό ν˜ΈμΆœν•˜κΈ° 전에 ZSTD_e_continue둜 μž…λ ₯의 μ΅œμ†Œ 1λ°”μ΄νŠΈλ₯Ό μ „λ‹¬ν•˜κ±°λ‚˜ 좜λ ₯ 버퍼가 < ZSTD_compressBound(inputSize) 인지 ν™•μΈν•˜μ‹­μ‹œμ˜€.

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

이것은 단일 패슀 MT μ••μΆ•κΈ°λ₯Ό μ μš©ν•˜λŠ” 것보닀 덜 λ°©ν•΄κ°€ 될 수 μžˆμŠ΅λ‹ˆλ‹€.
이 보증을 μ œκ³΅ν•˜λ„λ‘ μ„€κ³„λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

λ„€, 그게 더 μ‰¬μšΈ κ²λ‹ˆλ‹€. μ‹±κΈ€ 패슀 MT μ••μΆ•κΈ°μ˜ λͺ¨λ“  μž‘μ—…μ„ ν•œ λ²ˆμ— μ‹œμž‘ν•΄μ•Ό ν•œλ‹€λŠ” 사싀을 잊고 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

μ €λŠ” ν•œλ•Œ 닀쀑 μŠ€λ ˆλ“œ μ••μΆ•μ—μ„œ 항상 μ°¨λ‹¨λ˜λŠ” ZSTD_compressStream3() ν•¨μˆ˜λ₯Ό μΆ”κ°€ν•˜λŠ” 것을 μ œμ•ˆν•˜κ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€.

일반적으둜 μ‚¬λžŒλ“€μ΄ 슀트리밍 μ••μΆ• 루프λ₯Ό μž‘μ„±ν•˜λŠ” 방식은 μ΅œλŒ€ν•œ μ•žμœΌλ‘œ μ§„ν–‰ν•˜μ§€ μ•ŠλŠ” 것이 크게 λΆˆνŽΈν•˜μ§€ μ•Šμ•„μ•Ό ν•©λ‹ˆλ‹€. 이와 같은 것을 μΆ”κ°€ν•œλ‹€λ©΄ μƒˆλ‘œμš΄ APIκ°€ ν•„μš”ν•˜μ§€ μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€. μ•„λ§ˆλ„ 그것을 μ œμ–΄ν•˜κΈ° μœ„ν•΄ μ••μΆ• λ§€κ°œλ³€μˆ˜λ₯Ό μΆ”κ°€ν•΄μ•Ό ν•  κ²ƒμž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ ν˜„μž¬λ‘œμ„œλŠ” 크게 ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λͺ¨λ“  3 λŒ“κΈ€

닀쀑 μŠ€λ ˆλ“œ zstd 의 κ²°κ³Όκ°€ μŠ€λ ˆλ“œμ˜ nb에 μ˜μ‘΄ν•˜μ§€ μ•ŠλŠ”λ‹€κ³  λ§ν•˜λŠ” 것은 μ§€λ¦„κΈΈμž…λ‹ˆλ‹€.

μ‹€μ œλ‘œ μ§€μ›λ˜λŠ” κΈ°λŠ₯은 _streaming_ multithreaded zstd 의 κ²°κ³Όκ°€ nb개의 μŠ€λ ˆλ“œμ— μ˜μ‘΄ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.
(그리고 이것이 zstd CLIμ—μ„œ μ‚¬μš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€).

이 μ •μ˜λ₯Ό 톡해 λ‹€λ₯Έ 잠재적인 μˆ˜μ • 사항을 κ³ λ €ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
nbWorkers >= 1 일 λ•Œ ZSTD_e_end λŒ€ν•œ μ›νŒ¨μŠ€ λ°”λ‘œ κ°€κΈ°λ₯Ό μ‚¬μš©ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€.
이 문제λ₯Ό μœ λ°œν•˜λŠ” 것은 μ›νŒ¨μŠ€ λͺ¨λ“œμ— λŒ€ν•œ μœ„μž„μ΄κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

이것은 단일 패슀 MT μ••μΆ•κΈ°λ₯Ό μ μš©ν•˜λŠ” 것보닀 덜 λ°©ν•΄κ°€ 될 수 μžˆμŠ΅λ‹ˆλ‹€.
이 보증을 μ œκ³΅ν•˜λ„λ‘ μ„€κ³„λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

또 λ‹€λ₯Έ (잠재적으둜 긍정적인) λΆ€μž‘μš©μ€ 슀트리밍 λ©€ν‹°μŠ€λ ˆλ“œ 압좕이 _항상_ λΉ„μ°¨λ‹¨μž„μ„ 보μž₯ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. (차단) 단일 패슀 λͺ¨λ“œμ— 더 이상 μœ„μž„ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.
_edit_ : ZSTD_e_flush 및 ZSTD_e_end μ§€μ‹œλ¬Έμ„ μˆ˜μ‹ ν•˜λ©΄ MT API 계약이 μ΅œμ†Œ 순방ν–₯ μ§„ν–‰μ—μ„œ μ΅œλŒ€ 진행.

또 λ‹€λ₯Έ (잠재적으둜 긍정적인) λΆ€μž‘μš©μ€ 슀트리밍 λ©€ν‹°μŠ€λ ˆλ“œ 압좕이 더 이상 차단 λͺ¨λ“œμ— μœ„μž„λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— 항상 λΉ„μ°¨λ‹¨μž„μ„ 보μž₯ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

λ‚˜λŠ” ν•œλ•Œ 닀쀑 μŠ€λ ˆλ“œ μ••μΆ•μ—μ„œ 항상 μ°¨λ‹¨λ˜λŠ” ZSTD_compressStream3() ν•¨μˆ˜λ₯Ό μΆ”κ°€ν•˜λŠ” 것을 μ œμ•ˆν•˜κ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€.

λ°œμ‹ μžκ°€ κ³„μ†ν•΄μ„œ non-blocking 진행 상황을 ν™•μΈν•˜λ©΄ 맀우 뢈편 ν•©λ‹ˆλ‹€.

νŽΈμ§‘ : 방금 μ°Ύμ•˜μŠ΅λ‹ˆλ‹€. 진행 상황을 ν™•μΈν•˜λŠ” 것이 그닀지 λΆˆνŽΈν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

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));

κ·ΈλŸ¬λ‚˜ 항상 ZSTD_compressStream3() μ°¨λ‹¨ν•˜λŠ” 것이 더 λ‚«μŠ΅λ‹ˆλ‹€. 쑰금 더 λΉ λ₯Ό 수 μžˆμŠ΅λ‹ˆλ‹€. IMO λ§Žμ€ ν”„λ‘œκ·Έλž˜λ¨Έ μ‚¬μš©μžλŠ” μ••μΆ• 진행λ₯ μ„ 얻을 ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

이것은 단일 패슀 MT μ••μΆ•κΈ°λ₯Ό μ μš©ν•˜λŠ” 것보닀 덜 λ°©ν•΄κ°€ 될 수 μžˆμŠ΅λ‹ˆλ‹€.
이 보증을 μ œκ³΅ν•˜λ„λ‘ μ„€κ³„λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

λ„€, 그게 더 μ‰¬μšΈ κ²λ‹ˆλ‹€. μ‹±κΈ€ 패슀 MT μ••μΆ•κΈ°μ˜ λͺ¨λ“  μž‘μ—…μ„ ν•œ λ²ˆμ— μ‹œμž‘ν•΄μ•Ό ν•œλ‹€λŠ” 사싀을 잊고 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

μ €λŠ” ν•œλ•Œ 닀쀑 μŠ€λ ˆλ“œ μ••μΆ•μ—μ„œ 항상 μ°¨λ‹¨λ˜λŠ” ZSTD_compressStream3() ν•¨μˆ˜λ₯Ό μΆ”κ°€ν•˜λŠ” 것을 μ œμ•ˆν•˜κ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€.

일반적으둜 μ‚¬λžŒλ“€μ΄ 슀트리밍 μ••μΆ• 루프λ₯Ό μž‘μ„±ν•˜λŠ” 방식은 μ΅œλŒ€ν•œ μ•žμœΌλ‘œ μ§„ν–‰ν•˜μ§€ μ•ŠλŠ” 것이 크게 λΆˆνŽΈν•˜μ§€ μ•Šμ•„μ•Ό ν•©λ‹ˆλ‹€. 이와 같은 것을 μΆ”κ°€ν•œλ‹€λ©΄ μƒˆλ‘œμš΄ APIκ°€ ν•„μš”ν•˜μ§€ μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€. μ•„λ§ˆλ„ 그것을 μ œμ–΄ν•˜κΈ° μœ„ν•΄ μ••μΆ• λ§€κ°œλ³€μˆ˜λ₯Ό μΆ”κ°€ν•΄μ•Ό ν•  κ²ƒμž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ ν˜„μž¬λ‘œμ„œλŠ” 크게 ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰