Concurrency 防止并发操作中的多次借用
我正在尝试并行化一个无限脉冲响应滤波器,表示为双四元级联: 输入数据分为5个块(列)。IIR有3个双四阶级联(行)。要运行双四元组(其中一个块),必须同时计算块左侧和下方的数据。块中的数字表示该块可能的最早计算顺序 我正在使用和尝试构建一个算法,该算法可以并行计算尽可能多的块Concurrency 防止并发操作中的多次借用,concurrency,rust,Concurrency,Rust,我正在尝试并行化一个无限脉冲响应滤波器,表示为双四元级联: 输入数据分为5个块(列)。IIR有3个双四阶级联(行)。要运行双四元组(其中一个块),必须同时计算块左侧和下方的数据。块中的数字表示该块可能的最早计算顺序 我正在使用和尝试构建一个算法,该算法可以并行计算尽可能多的块 extern crate scoped_threadpool; use scoped_threadpool::Pool; use std::sync::mpsc::channel; fn main() {} pub
extern crate scoped_threadpool;
use scoped_threadpool::Pool;
use std::sync::mpsc::channel;
fn main() {}
pub struct BiQuad {}
impl BiQuad {
pub fn new() -> BiQuad {
BiQuad {}
}
#[inline]
pub fn apply(&mut self, _data: &mut [f64]) {}
}
pub struct Filter {
biquads: Vec<BiQuad>,
}
impl Filter {
pub fn new() -> Filter {
Filter {
biquads: Vec::new(),
}
}
pub fn add_biquad(&mut self, biquad: BiQuad) {
self.biquads.push(biquad);
}
pub fn apply_concurrently(&mut self, data: &mut [f64], threads: usize) {
apply_concurrently_internal(&mut self.biquads, data, threads);
}
}
fn apply_concurrently_internal(biquads: &mut [BiQuad], data: &mut [f64], threads: usize) {
if !biquads.is_empty() {
let mut pool = Pool::new(threads as u32);
let (tx, rx) = channel();
let tx2 = tx.clone();
let chunk_size = data.len() / threads;
tx.send((0, 0, data.split_at_mut(chunk_size), biquads.split_at_mut(1)));
pool.scoped(|scope| {
loop {
match rx.recv() {
Ok((
biquad,
block,
(chunk_data, remaining),
(current_biquad, cascading_biquads),
)) => {
let inner_tx = tx2.clone();
println!("got here: {} - {}", biquad, block);
scope.execute(move || {
current_biquad[0].apply(chunk_data);
//Move horizontally (through data)
inner_tx.send((
biquad,
block + 1,
remaining.split_at_mut(chunk_size),
(current_biquad, cascading_biquads),
));
//Move vertically (cascade)
inner_tx.send((
biquad + 1,
block,
(chunk_data, &mut []),
cascading_biquads.split_at_mut(1),
));
});
}
Err(_) => break,
}
}
});
}
}
此外,如前所述,没有任何东西可以阻止块2,2在第三个位置而不是至少在第四个位置执行
这是一个我可以用Rust(无所畏惧!)并发特性优雅地解决的问题吗?在并发操作既共享数据又相互依赖的情况下,是否有解决方案?不要通过共享内存进行通信;通过交流分享记忆。我认为你的方法有点错误。您永远不会需要超过三个线程,每行一个。每行将从左到右处理其单元格。处理一个单元将阻止它的下邻居准备就绪(它的左邻居必须准备就绪)@PeterHall,我同意这是错误的。问题是线程需要在网格上呈对角线。如果依赖仅仅是一种方式,那就很容易了。Shepmaster,你是说共享内存是数据和双四元组,应该在收到消息时提取吗?我试过了,但是我遇到了同样的问题,一旦池中的线程尝试获取共享数据,它就需要从某个地方借用它……一旦池中的线程尝试获取共享数据,它就需要从某个地方借用它——但是为什么要共享任何东西,尤其是可变的东西呢?将工作分散到线程,然后将其发送回一个线程以将其存储在某个位置。否则,您很可能会被错误共享搞得筋疲力尽。如果每个线程都必须处理数据的一个副本,那么性能就会受到影响。