8000 Add multi-threading compression by Cyan4973 · Pull Request #1336 · lz4/lz4 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add multi-threading compression #1336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 53 commits into from
Dec 30, 2023
Merged

Add multi-threading compression #1336

merged 53 commits into from
Dec 30, 2023

Conversation

Cyan4973
Copy link
Member
@Cyan4973 Cyan4973 commented Dec 29, 2023

This patch adds multi-threading support for compression to the lz4 CLI.

Features :

  • Display if the binary supports multithreading or not (welcome message)
  • Automatically select a nb of threads, based on local cpu
    • can also be controlled manually
  • Provides a detailed summary in verbose mode, featuring speed and cpu utilization

Here are a few results using this patch :

cpu corpus c.level v1.9.4 this PR speedup
i7-9700 enwik9 1 2.3 s 0.45 s x5.1
i7-9700 silesia.tar 9 5.5 s 1.0 s x5.5
i7-9700 silesia.tar 12 17 s 3.0 s x5.6
i7-9700 enwik9 9 23 s 4.1 s x5.6
M1 Pro enwik9 1 2.2 s 0.42 s x5.2
M1 Pro silesia.tar 9 5.1 s 0.75 s x6.8
M1 Pro silesia.tar 12 16.5 s 2.5 s x6.6
M1 Pro enwik9 9 21 s 3.0 s x7.0

This is a pretty big patch, and I would expect various issues to crop up during testings.
Therefore it's going to be important to test this feature thoroughly before considering building a new release around it.

Open discussions on #1334

Known current limitations :

  • Requires pthread (i.e. mostly posix environments)
  • Compression only
  • Independent blocks only (revert to single thread for linked blocks)
  • When there are multiple files, they are still processed sequentially

Cyan4973 and others added 30 commits December 27, 2023 23:32
and automatic determination
no longer tied to Legacy format:
receive buffer sizes as parameters.
- no crc
- no stdin support
- no dictionary support
- relatively wasteful resource management
currently not active : behave as if blocks are still independent
- traces display line number
- errors display traces (debuglevel >= 3)
Note: effectively limited to using the dictionary once for now,
as opposed to once per block when blocks are independent
(no impact when blocks are linked: dictionary is supposed to be used once anyway)

Also :
- clarifies that default lz4frame block size is 64 KB
- refactor LZ4 Frame spec, dictionary paragraph
- updated manual
now lz4 build defaults to single-thread mode
though it still builds single-threaded lz4
mostly for C++98 compatibility
(which benefit is dubious, this policy could be revisited)
and make it build the MT version of lz4
with an option that is enabled by default but can be disabled on demand.

Also :
- added make target mesonbuild, for easy local build
- made huge tests friendlier to MT variant, for faster testing time
and some minor printf limitations on Windows.
@Cyan4973 Cyan4973 force-pushed the asyncio branch 3 times, most recently from c585380 to 043f625 Compare December 30, 2023 01:39
also:
display time/cpu statistics after legacy compression
}
} else {
/* some other error */
goto failed;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may not happen. But we can think about the following scenario :

  • glpi() returns ERROR_INSUFFICIENT_BUFFER at the first time.
  • buffer is allocated, while() loop continues.
  • glpi() fails at the second time. (for some reason)
  • Here, potentially buffer will be leaked.

In scenarios where there are many files,
instead of recreating and freeing thread pool for every file
do it once, and share it across all files.

The impact is small, but can be measured:
in a scenario compressing a lot of files of 5 MB at level 1 with 6 threads,
compression time went down from 3 sec to 2.8 sec.
lz4 skips multithreading for small files.

In a scenario invoking lz4 repetitively on a lot of small files,
processing time goes down from 5.5 sec to 4.5 sec.
@Cyan4973 Cyan4973 merged commit 4b407c3 into dev Dec 30, 2023
@Cyan4973 Cyan4973 deleted the asyncio branch January 2, 2024 18:32
bennetthardwick pushed a commit to foxglove/mcap that referenced this pull request Jun 12, 2025
### Changelog

This PR adds two new write options:
* `compression_level: u32` – compression level to use for zstd/lz4, or
zero to use the default compression level.
* `compression_threads: u32` - number of threads to use for compression,
or zero to disable multithreaded compression.

### Docs

None? Let me know if I need to update docs somewhere.

### Description

Prior to this PR, it wasn't possible to set the compression level; the
default lz4 and zstd compression levels were used. Now, it's possible to
set the lz4 and zstd compression levels.

Prior to this PR, non-wasm targets were forced to use multithreaded zstd
compression
([reference](https://github.com/foxglove/mcap/blob/b404e42bd9ca6e9193ae994f7f3d752248ea8b06/rust/src/write.rs#L1368)).
Now, it's possible to disable multithreaded compression, or to use a
different number of compression threads.

lz4 supports multithreaded compression as of v1.10.0 (see
[[1]](https://github.com/lz4/lz4/releases/tag/v1.10.0) and
[[2]](lz4/lz4#1336)), but this feature doesn't
seem to be accessible from the [lz4](https://crates.io/crates/lz4) /
[lz4-sys](https://crates.io/crates/lz4-sys) crates. For now, the
`compression_level` option is ignored when using lz4 compression. Let me
know if we should print a warning or fail.

I made these write options rather than parameterizing the
[`Compression`](https://github.com/foxglove/mcap/blob/b404e42bd9ca6e9193ae994f7f3d752248ea8b06/rust/src/lib.rs#L158)
enum variants, because these particular options are orthogonal to the
compression algorithm, and because they're only applicable to writers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0