Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.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
Concurrency 防止并发操作中的多次借用_Concurrency_Rust - Fatal编程技术网

Concurrency 防止并发操作中的多次借用

Concurrency 防止并发操作中的多次借用,concurrency,rust,Concurrency,Rust,我正在尝试并行化一个无限脉冲响应滤波器,表示为双四元级联: 输入数据分为5个块(列)。IIR有3个双四阶级联(行)。要运行双四元组(其中一个块),必须同时计算块左侧和下方的数据。块中的数字表示该块可能的最早计算顺序 我正在使用和尝试构建一个算法,该算法可以并行计算尽可能多的块 extern crate scoped_threadpool; use scoped_threadpool::Pool; use std::sync::mpsc::channel; fn main() {} pub

我正在尝试并行化一个无限脉冲响应滤波器,表示为双四元级联:

输入数据分为5个块(列)。IIR有3个双四阶级联(行)。要运行双四元组(其中一个块),必须同时计算块左侧和下方的数据。块中的数字表示该块可能的最早计算顺序

我正在使用和尝试构建一个算法,该算法可以并行计算尽可能多的块

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,你是说共享内存是数据和双四元组,应该在收到消息时提取吗?我试过了,但是我遇到了同样的问题,一旦池中的线程尝试获取共享数据,它就需要从某个地方借用它……一旦池中的线程尝试获取共享数据,它就需要从某个地方借用它——但是为什么要共享任何东西,尤其是可变的东西呢?将工作分散到线程,然后将其发送回一个线程以将其存储在某个位置。否则,您很可能会被错误共享搞得筋疲力尽。如果每个线程都必须处理数据的一个副本,那么性能就会受到影响。