How can I sum up using concurrency from 1 to 1000000 with Rust?

前端 未结 1 900
醉梦人生
醉梦人生 2021-01-25 21:49

I am a newbie to Rust, and I want to sum up a large amount of numbers using concurrency. I found this code:

use std::thread;
use std::sync::{Arc, Mutex};

static         


        
相关标签:
1条回答
  • There are several problems with the provided code.

    1. thread::spawn creates an OS-level thread, which means the existing code cannot possibly scale to numbers up to a million as indicated in the title. That would require a million threads in parallel, where typical modern OS'es support up to a few thousands of threads at best. More constrained environments, such as embedded systems or virtual/paravirtual machines, allow much less than that; for example, the Rust playground appears to allow a maximum of 24 concurrent threads. Instead, one needs to create a fixed small number of threads, and carefully divide the work among them.
    2. The function executing in each thread runs inside a lock, which effectively serializes the work done by the threads. Even if one could spawn arbitrarily many threads, the loop as written would execute no faster than what would be achieved by a single thread - and in practice it would be orders of magnitude slower because it would spend a lot of time on locking/unlocking of a heavily contended mutex.

    One good way to approach this kind of problem while still managing threads manually is provided in the comment by Boiethios: if you have 4 threads, just sum 1..250k, 250k..500k, etc. in each thread and then sum up the return of the threaded functions.

    Or is there another way to sum up from 1 to 1000000 with concurrency?

    I would recommend using a higher-level library that encapsulates creation/pooling of worker threads and division of work among them. Rayon is an excellent one, providing a "parallel iteration" facility, which works like iteration, but automatically dividing up the work among multiple cores. Using Rayon, parallel summing of integers would look like this:

    extern crate rayon;
    
    use rayon::prelude::*;
    
    fn main() {
        let sum: usize = (1..1000001).collect::<Vec<_>>().par_iter().sum();
        assert_eq!(sum, 500000500000);
    }
    
    0 讨论(0)
提交回复
热议问题