arrays - 使用索引数组并行写入数组

标签 arrays concurrency rust parallel.foreach

我无法理解来自 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;
    });
}

playground

编辑

根据评论,您可以让每个元素都是原子的:

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);
    });
}

关于arrays - 使用索引数组并行写入数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64423043/

相关文章:

arrays - 在带有数组的语句中使用 OR,(C)

C数组变化导致变量修改

java - 使用 ForkJoin 和 Streams 构建自适应网格细化

ios - 对于 iOS,Concurrency Programming Guide 和 Threading Programming Guide 有什么区别?

memory - 为什么内存地址打印的是{:p} much bigger than my RAM specs?

rust - "the trait is not implemented for Self"尽管它完全是

syntax - 让 &mut 语法

php - 将键值对的 PHP 数组转换为分层嵌套树结构

javascript - CSS 只绘制左边框和上边框,忽略右边框和下边框

应用 java AtomicIntegeraccumulateAndGet