Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Rust中大内存块的并行初始化_Multithreading_Rust - Fatal编程技术网

Multithreading Rust中大内存块的并行初始化

Multithreading Rust中大内存块的并行初始化,multithreading,rust,Multithreading,Rust,最好的方法是什么: 我有一个2GB内存块,需要用一些数据初始化。 数据都是独立的,因此我可以很容易地生成n个线程来初始化数据,每个线程在单独的内存位置上并行工作 我怎样才能“告诉”这个生锈。它不允许我在线程之间共享内存(这是有充分理由的,也是理所当然的)。我知道不会有竞争条件,因为每个线程在完全不同的内存位置上工作 一个想法是使用(横梁)通道。每个线程将计算发送到一个写入程序,该写入程序将内存放入正确的位置。唉,这感觉过于复杂,效率不够。是否有一些方法可以对线程的内存进行分区,以确保使用不同的线

最好的方法是什么:

我有一个2GB内存块,需要用一些数据初始化。 数据都是独立的,因此我可以很容易地生成n个线程来初始化数据,每个线程在单独的内存位置上并行工作

我怎样才能“告诉”这个生锈。它不允许我在线程之间共享内存(这是有充分理由的,也是理所当然的)。我知道不会有竞争条件,因为每个线程在完全不同的内存位置上工作


一个想法是使用(横梁)通道。每个线程将计算发送到一个写入程序,该写入程序将内存放入正确的位置。唉,这感觉过于复杂,效率不够。是否有一些方法可以对线程的内存进行分区,以确保使用不同的线程进行操作时安全?

并行性的go-to板条箱是,这可以简化:

use rayon::prelude::*;

// this just takes a big zeroed buffer and fills it with 1s with 10 threads
fn main() {
    let mut data = vec![0u8; 2000000]; // pretend this is 2 GiB
    data.chunks_mut(200000) // pretend this is 2 GiB / N threads
        .par_bridge()
        .for_each(|d| d.fill(1));
}

用于切片的
chunks\u mut()
函数已经可以为您提供许多可变切片,以分离原始图像的各个区域。然后,只需使用
par_bridge()
将其转换为并行迭代器。

并行化的目标是,这可以简化:

use rayon::prelude::*;

// this just takes a big zeroed buffer and fills it with 1s with 10 threads
fn main() {
    let mut data = vec![0u8; 2000000]; // pretend this is 2 GiB
    data.chunks_mut(200000) // pretend this is 2 GiB / N threads
        .par_bridge()
        .for_each(|d| d.fill(1));
}

用于切片的
chunks\u mut()
函数已经可以为您提供许多可变切片,以分离原始图像的各个区域。然后,只需使用
par_bridge()
将其转换为并行迭代器。

除了kmdreko推荐的优秀人造丝板条箱之外,还有一个更低级的原语,可以实现您想要的。您可以使用它将现有可变切片拆分为多个可变切片,而无需使用不安全代码:

let mut data = vec![0u8; 2_000_000]; // pretend this is 2 GiB
let mut data = &mut data[..];
let chunk_size = data.len() / n_threads;

for _ in 0..n_threads {
    let (chunk, rest) = data.split_at_mut(chunk_size);
    data = rest;
    spawn(move |_| {
        chunk.fill(1);
    });
}
但是,要使其工作,您需要作用域线程,即允许引用借用值的线程。(这是合理的,因为作用域线程会自动连接所有创建的线程,从而确保没有线程比借用的值更长寿。)

下面是一个例子,使用与kmdreko的回答类似的设置:

use crossbeam_utils::thread;

fn main() {
    let n_threads = 8;
    let mut data = vec![0u8; 2_000_000]; // pretend this is 2 GiB
    let mut data = &mut data[..];
    let chunk_size = data.len() / n_threads;
    thread::scope(|s| {
        for _ in 0..n_threads {
            let (chunk, rest) = data.split_at_mut(chunk_size);
            data = rest;
            s.spawn(move |_| {
                chunk.fill(1);
            });
        }
    })
    .unwrap();
}

除了kmdreko推荐的优质人造丝板条箱之外,还有一种更低级的原型机,可以满足您的需求。您可以使用它将现有可变切片拆分为多个可变切片,而无需使用不安全代码:

let mut data = vec![0u8; 2_000_000]; // pretend this is 2 GiB
let mut data = &mut data[..];
let chunk_size = data.len() / n_threads;

for _ in 0..n_threads {
    let (chunk, rest) = data.split_at_mut(chunk_size);
    data = rest;
    spawn(move |_| {
        chunk.fill(1);
    });
}
但是,要使其工作,您需要作用域线程,即允许引用借用值的线程。(这是合理的,因为作用域线程会自动连接所有创建的线程,从而确保没有线程比借用的值更长寿。)

下面是一个例子,使用与kmdreko的回答类似的设置:

use crossbeam_utils::thread;

fn main() {
    let n_threads = 8;
    let mut data = vec![0u8; 2_000_000]; // pretend this is 2 GiB
    let mut data = &mut data[..];
    let chunk_size = data.len() / n_threads;
    thread::scope(|s| {
        for _ in 0..n_threads {
            let (chunk, rest) = data.split_at_mut(chunk_size);
            data = rest;
            s.spawn(move |_| {
                chunk.fill(1);
            });
        }
    })
    .unwrap();
}

没有细节,很难给你一个精确的解决方案。但是你应该看看这个例子:这能回答你的问题吗?没有细节,很难给你一个精确的解决方案。但是你应该看看这个例子:这能回答你的问题吗?