Skip to content
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

Multithreaded compression #96

Open
Smotrov opened this issue May 25, 2023 · 2 comments
Open

Multithreaded compression #96

Smotrov opened this issue May 25, 2023 · 2 comments

Comments

@Smotrov
Copy link

Smotrov commented May 25, 2023

It was mentioned in the announcement that "Multithreaded compression allows multiple threads to operate in unison on a single file." However, I've been struggling to find any documentation or examples that illustrate this feature. I would greatly appreciate it if someone could share a code snippet or example showing how to utilize this new functionality.
I suspect it is compress_multi, but the last parameter alloc_per_thread is unclear for me.

@danielrh
Copy link
Collaborator

You should pass an allocator per thread so that it can allocate from each thread. If your allocator is thread safe then you can share the same one.

@Smotrov
Copy link
Author

Smotrov commented May 1, 2024

Thank you @danielrh!

I'm not sure if this is correct approach.
Meanwhile I do not have a clear understanding of SliceWrapper purpose and second parameter of SendAlloc::new.

I also have 2 questions:

  • What to do if I can not predict output length? Now it s 1000. When it is just Vec::new() there is an error.
  • The more cores I set the bigger number is returned by compress_multi. How to explain this?
use brotli::enc::multithreading::compress_multi;
use brotli::enc::threading::SendAlloc;
use brotli::enc::backward_references::BrotliEncoderParams;
use brotli::enc::{StandardAlloc, Owned};
use brotli::enc::UnionHasher;

// Adjust number of threads
const CPU_CORES: usize = 16;

struct MySliceWrapper(Vec<u8>);

impl brotli::enc::SliceWrapper<u8> for MySliceWrapper {
    fn slice(&self) -> &[u8] {
        &self.0
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let params = BrotliEncoderParams::default();
    let data = MySliceWrapper(b"Example data to compress".to_vec());
    let mut owned_input = Owned::new(data);
    let mut output = vec![0u8; 10000]; // Adjust the size according to your needs

    let alloc = StandardAlloc::default(); // Adjust based on your allocation strategy

    let mut alloc_per_thread = Vec::with_capacity(CPU_CORES);


    for _ in 0..CPU_CORES {
        alloc_per_thread.push(SendAlloc::new(alloc,UnionHasher::Uninit));
    }

    let result = compress_multi(&params, &mut owned_input, &mut output, &mut alloc_per_thread).unwrap();
    println!("Compressed bytes: {}", result);

    Ok(())
}

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

No branches or pull requests

2 participants