Paralleles Schreiben in ein Array mit einem Index-Array [Duplikat]
Ich habe Probleme, das Parallelitätsmodell in Rust zu verstehen, das aus C ++ stammt.
Auf mein Array soll gleichzeitig mit einem anderen Array zugegriffen werden, das die Indizes definiert. Zum Beispiel (Pseudocode):
let indices = [1, 2, 3, 4, 1, 2, 3, 2, 1, 1, 3, 2, 2];
let mut arr = [1, 2, 3, 4, 5, 6, 7, 8, 10];
indices.iter_par().for_each(|x| {
arr[x] += x;
});
In C ++ würde ich jeden Index arrmit einer Sperre schützen oder atomaren Zugriff verwenden. Wie könnte ich dasselbe in Rust tun?
BEARBEITEN
Ich habe noch eine verwandte Frage.
Wie könnte ich ein normales Array als veränderlich an den parallelen Iterator übergeben, wo ich sicher bin, dass keine Race-Bedingungen auftreten können?
let indices = [1, 2, 3, 4, 5, 6, 7, 8];
let mut arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
indices.iter_par().for_each(|x| {
arr[x] = some_function(x);
});
Antworten
Ich weiß nicht, wozu diese Operation parallel ausgeführt werden soll, wenn Sie für jedes Element eine Sperre benötigen, aber Sie können dies erreichen, indem Sie ein Mutexum das Array herum mutieren:
use rayon::prelude::*;
use std::sync::Mutex;
fn main() {
let indices = [1, 2, 3, 4, 1, 2, 3, 2, 1, 1, 3, 2, 2];
let arr = Mutex::new([1, 2, 3, 4, 5, 6, 7, 8, 10]);
indices.par_iter().for_each(|&x| {
let mut arr = arr.lock().unwrap();
arr[x] += x;
});
}
Spielplatz
BEARBEITEN
Basierend auf dem Kommentar können Sie jedes Element atomar sein lassen:
use rayon::prelude::*;
use std::sync::atomic::{AtomicUsize, Ordering};
fn main() {
let indices = [1, 2, 3, 4, 1, 2, 3, 2, 1, 1, 3, 2, 2];
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 10]
.iter()
.map(|&n| AtomicUsize::new(n))
.collect::<Vec<_>>();
indices.par_iter().for_each(|&x| {
arr[x].fetch_add(x, Ordering::SeqCst);
});
}