使用索引数组并行写入数组
Parallel write to array with an indices array
我无法理解来自 C++ 的 Rust 中的并发模型。
我的数组将使用定义索引的另一个数组同时访问。例如(伪代码):
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;
});
在 C++ 中,我会使用锁或原子访问来保护 arr
中的每个索引。我怎么能在 Rust 中做同样的事情?
编辑
我还有一个相关问题。
我如何才能将普通数组作为可变数组传递给并行迭代器,我确定不会出现竞争条件?
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);
});
如果您需要为每个项目锁定,我不知道并行执行此操作的意义是什么,但您可以使用数组周围的 Mutex
进行变异来实现此目的:
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;
});
}
编辑
根据评论,您可以让每个元素都是原子的:
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);
});
}
我无法理解来自 C++ 的 Rust 中的并发模型。
我的数组将使用定义索引的另一个数组同时访问。例如(伪代码):
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;
});
在 C++ 中,我会使用锁或原子访问来保护 arr
中的每个索引。我怎么能在 Rust 中做同样的事情?
编辑
我还有一个相关问题。
我如何才能将普通数组作为可变数组传递给并行迭代器,我确定不会出现竞争条件?
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);
});
如果您需要为每个项目锁定,我不知道并行执行此操作的意义是什么,但您可以使用数组周围的 Mutex
进行变异来实现此目的:
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;
});
}
编辑
根据评论,您可以让每个元素都是原子的:
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);
});
}