本文介绍了并行处理vec:如何安全地进行操作,或不使用不稳定的功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个庞大的向量,希望能够并行加载/操作,例如在一个线程中加载前十万个索引,在另一个线程中加载,依此类推.由于这将是代码中非常热门的部分,因此我提出了以下以下概念证明不安全的代码,以在没有Arcs和Mutexes的情况下执行此操作:

I have a massive vector that I want to be able to load/act on in parallel, e.g. load first hundred thousand indices in one thread, next in another and so on. As this is going to be a very hot part of the code, I have come up with this following proof of concept unsafe code to do this without Arcs and Mutexes:

let mut data:Vec<u32> = vec![1u32, 2, 3];
let head = data.as_mut_ptr();
let mut guards = (0..3).map(|i|
  unsafe {
    let mut target = std::ptr::Unique::new(head.offset(i));
    let guard = spawn(move || {
      std::ptr::write(target.get_mut(), 10 + i as u32);
    });
    guard
  });

我在这里想念的东西有什么可能使它爆炸吗?

Is there anything I have missed here that can make this potentially blow up?

这使用#![feature(unique)],所以我看不到如何稳定地使用它.有没有一种方法可以稳定地执行这种操作(理想情况下是安全的,无需使用原始指针和ArcMutex的开销)?

This uses #![feature(unique)] so I don't see how to use this in stable. Is there a way to do this sort of thing in stable (ideally safely without using raw pointers and overhead of Arc's and Mutex's)?

还要查看 Unique 的文档,它说

Also, looking at documentation for Unique, it says

我不清楚唯一路径"是什么意思.

I am not clear what "unique path" means.

推荐答案

今天, rayon 板条箱是这类事情的事实上的标准:

Today the rayon crate is the de facto standard for this sort of thing:

use rayon::prelude::*;

fn main() {
    let mut data = vec![1, 2, 3];
    data.par_iter_mut()
        .enumerate()
        .for_each(|(i, x)| *x = 10 + i as u32);
    assert_eq!(vec![10, 11, 12], data);
}

请注意,这与使用标准迭代器的单线程版本只有一行不同,后者将par_iter_mut替换为iter_mut.

Note that this is just one line different from the single-threaded version using standard iterators, which would replace par_iter_mut with iter_mut.

另请参见在Rust和Zig中编写一个小型光线跟踪器.

这篇关于并行处理vec:如何安全地进行操作,或不使用不稳定的功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-28 06:38