Multithread matrix multiplication


#1

Hi everyone! First of all - sorry for my english :slight_smile:
Always used to write on C, but now i have to do kind of homework using rust and it’s really hard to understand some things. The algorithm is:

  1. ask dimensions of matrix

  2. put random numbers there

  3. create 2 threads, and give each of them to count a half of rows for answer matrix

  4. print answer
    the 3rd step looks like that:

                  let fthr = thread::spawn( move || {
                              	for z in 0..half {
                                 for i in 0..d{
                                        for j in 0..a{
     	                                 resultM[z][i]+=(firstM[z][j])*(secondM[j][i]);}	}    }
                                                                        });
    
                 let sthr = thread::spawn(move || { 
                                for z in half..a {
                                for i in 0..d{
                                        for j in 0..a{
     	                                 resultM[z][i]+=(firstM[z][j])*(secondM[j][i]);}  	}    }
                                                                       });
    

And of course i got error “used moved value” for second thread and both 3 matrix. But what should i use to share them? channels? mutex? Just don’t know what is the right way to solve this problem
Thanks!


#2

You should split_at_mut (slice function) the result to create two different slices and pass each half to the relevant thread.

For the two input, you need not to move them (which you are, since you used move), but access them from behind a reference.

Conceptually you don’t need a mutex:

  • Each thread writes to disjoint memory areas
  • The input remain unchanged

#3

Сould you please explain how to use references here?
If i don’t use “move” it asks me to do this


#4

std::thread::spawn does not support scoped threads or in other words, does not support threads that borrow from an outer scope, like you’d need to do to use split_at_mut.

Many libraries offer scoped threads, including rayon which has a simple join(a, b) function that splits work into two parallel parts.

Using std::thread::spawn while still sharing (dynamic, as in non-static) memory requires using the reference counting smart pointer Arc for shared ownership.


#5

BTW Crossbeam has scoped threads: https://docs.rs/crossbeam/0.3.0/crossbeam/struct.Scope.html#method.spawn


#6

Thank you so much! Now everything works good.