gpt4 book ai didi

multithreading - 在使用 MPSC channel 时,Rust 提供了哪些工具来避免复制?

转载 作者:行者123 更新时间:2023-11-29 08:07:36 25 4
gpt4 key购买 nike

我正在使用 mpsc 创建一个多线程应用程序以在我的线程之间共享内存:

use std::thread;
use std::sync::mpsc::{Sender, Receiver};

#[derive(Debug)]
struct Msg {
pub content: Vec<i16>,
/* ... */
}

#[derive(Debug)]
struct MsgBack {
pub content: Vec<i16>,
pub new_content: Vec<i16>,
/* ... */
}

fn child(rx: mpsc::Receiver<Msg>, tx: mpsc::Sender<MsgBack>) {
let message = rx.recv().unwrap();
let new_content = message.content.iter().map(|x| -x).collect();

tx.send(MsgBack { // The memory is moved/copied
content: message.content,
new_content: new_content,
});
}

fn main() {
let (tx, rx): (Sender<Msg>, Receiver<Msg>) = mpsc::channel();
let (tx_back, rx_back): (Sender<MsgBack>, Receiver<MsgBack>) = mpsc::channel();

thread::spawn(move || {
child(rx, tx_back);
});

let message = Msg {
content: (0..100).map(|x| x).collect(), // Dummy initialisation
};
println!("{:#?}", message);
tx.send(message).unwrap(); // The memory is moved/copied

let answer = rx_back.recv().unwrap();
println!("{:#?}", answer);
}

我做了一些分析,发现发送数据占我实际程序执行时间的 1/3(发送的不仅仅是 Vec)。

我想保留此代码结构,但在发送消息时避免移动/复制以节省大量时间。

最佳答案

移动 Vec不移动其内容,但只移动 3 个字的“标题”。因此,除非您的 MsgBack包含很多其他字段或内联的大型固定大小数组,移动起来应该很便宜。

一般情况下,可以把东西放在Box里面在堆上分配它们,那么 Box<T>本身只是指针大小。 Box的“搬家”不移动任何数据,只复制指针。


如果您的实际迭代器比您的示例更复杂并且没有用 size_hint ,您可能会看到 memcpy来自 .collect()随着向量的增长重新分配向量。您可以通过预先分配所需的大小来避免这种情况:

代替:

let dst = iterator.collect();

使用:

let mut dst = Vec::with_capacity(required_size);
dst.extend(iterator);

关于multithreading - 在使用 MPSC channel 时,Rust 提供了哪些工具来避免复制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49365248/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com