2

I have a vector of u8 and I need to fill this vector with values that can be computed in parallel:

let vector: Vec<u8> = vec![0, len];

Given n_threads threads, each thread can take care of a section of the vector. The only way I know of to pass a mutable vector into multiple threads is to wrap it into a Mutex:

let vector: Arc::new(Mutex::new(vec![0, len]));

and for each thread move the clone of the atomic reference:

for _ in 0..n_hthreads {
    let vector = Arc::clone(&vector);
    thread::spawn(move || fill_vector());
}

The problem with this approach is that I would need to lock the entire vector inside the threads (which completely nullifies the parallelism):

fn fill_vector() {
    let vector = vector.lock().unwrap();
    vector[i] = /* ... */;
}

A possible alternative would be to have multiple vectors and pass each vector to each thread, and once the threads are joined concatenate the vectors, but that would require additional memory unless there is a way to move the sub-vectors into the final vector instead of copying them.

Is there any alternative that would allow me to lock only a specific section of the vector or to move multiple sub-vectors when concatenating (my goal is to have a single vector in the end), or any other alternative to safely write into the vector?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Nick
  • 10,309
  • 21
  • 97
  • 201
  • 1
    See also [`par_chunks_mut`](https://docs.rs/rayon/1.0.2/rayon/slice/trait.ParallelSliceMut.html#method.par_chunks_mut). [Full example](https://play.rust-lang.org/?gist=fa1c6a757685160a19fd20ce3c4408a2&version=stable&mode=debug&edition=2015) – Shepmaster Sep 26 '18 at 17:39
  • @Shepmaster From the duplicate answers looks like there is no way to do it by using the language itself or any standard library. Am I correct? – Nick Sep 26 '18 at 18:02
  • 1
    I don't understand your meaning. The libraries used in the linked questions are written using the Rust language, so yes, it's definitely possible to write it using the language itself. No, there's nothing in the standard library that does it for you (as at least one of the duplicates starts out by saying). The majority of the Rust community is happy to use code that other people have written because Cargo makes it so easy. If you aren't one of this group, just copy and paste the source code from any Open Source library you'd like and then you don't have to worry about dependencies. – Shepmaster Sep 26 '18 at 18:07
  • 1
    @Shepmaster There is a difference between being part of the language and being part of a library (string/Vec), and there is a difference between being part of the standard library and being a 3rd party library. I am not complaining don't get me wrong, just commenting on how strange I find such a common task not being achievable by simply using the standard library. – Nick Sep 26 '18 at 18:14
  • Assuming it's common is not something I'd agree with. I'd also say that generating a random number is far more common and [that's not part of the standard library, either](https://stackoverflow.com/q/29334461/155423). In my experience, everyone tends to think that the things that *they* do are things that *everyone* does. – Shepmaster Sep 26 '18 at 18:21
  • 1
    @Shepmaster `crossbeam` worked perfectly and it's very easy to use. Thanks! – Nick Sep 27 '18 at 15:56

0 Answers0