thread::available_parallelism în Rust

Estimează câte fire pot rula cu adevărat în paralel pe calculator (de obicei numărul de nuclee logice).

Sintaxă
pub fn available_parallelism() -> io::Result<NonZero<usize>>

Ce face thread::available_parallelism

available_parallelism() spune câte fire poate rula sistemul în același timp, adică de obicei numărul de nuclee logice ale procesorului, ținând cont de limitele impuse procesului (de exemplu într-un container). Este un punct de pornire bun pentru numărul de fire de lucru.

Rezultatul este io::Result<NonZero<usize>>: un număr garantat mai mare decât 0, într-un Result, pentru că pe unele sisteme informația nu poate fi aflată. Valoarea se obține cu .get().

Ce returnează

Ok(NonZero<usize>) cu numărul estimat sau Err dacă nu poate fi aflat.

Exemple

Exemplul 1: Câte fire pot rula în paralel

Numărul depinde de calculator; pe un procesor cu 8 nuclee logice, rezultatul este 8.

use std::thread;

fn main() {
    let n = thread::available_parallelism().map(|n| n.get()).unwrap_or(1);
    println!("Fire în paralel: {n}");
}

Rezultat (depinde de calculator)

Fire în paralel: 8

Exemplul 2: Împarte munca după numărul de nuclee

Indiferent câte bucăți ies, suma finală este aceeași.

use std::thread;

fn main() {
    let fire = thread::available_parallelism().map(|n| n.get()).unwrap_or(1);
    let numere: Vec<u64> = (1..=1000).collect();
    let marime = numere.len().div_ceil(fire);

    let suma: u64 = thread::scope(|s| {
        let parti: Vec<_> = numere.chunks(marime).map(|b| s.spawn(move || b.iter().sum::<u64>())).collect();
        parti.into_iter().map(|h| h.join().unwrap()).sum()
    });
    println!("cel puțin un fir: {}", fire >= 1);
    println!("suma 1..=1000 = {suma}");
}

Rezultat

cel puțin un fir: true
suma 1..=1000 = 500500

Greșeli frecvente

  • Presupui că valoarea este mereu numărul de nuclee fizice: este o estimare (nuclee logice, limite de container) și poate fi diferită.
  • Scrii available_parallelism().unwrap() într-o bibliotecă: pe unele platforme funcția returnează Err. Folosește unwrap_or(1).

Comenzi înrudite

  • thread::spawn: Pornește un fir de execuție nou care rulează funcția dată; join() așteaptă terminarea lui și îi dă rezultatul.
  • thread::scope: Pornește fire care pot împrumuta variabile locale; scope așteaptă automat terminarea tuturor firelor create în el.