Multithreading 如何从多个线程初始化Vec?

Multithreading 如何从多个线程初始化Vec?,multithreading,rust,parallel-processing,atomic,Multithreading,Rust,Parallel Processing,Atomic,我有一段代码,它通过并行读取多个拼花文件、预处理数据,然后最终获取互斥体以顺序写入稀疏数组数据结构来生成CSR稀疏矩阵。这大致是每个线程的伪代码: read parquet data get list of nonzero values acquire mutex append nonzero values to sparse array (basically memcpy) release mutex repeat 代码的速度不会随着CPU的增加而提高,因此我怀疑互斥争用是一个瓶颈。因此,我

我有一段代码,它通过并行读取多个拼花文件、预处理数据,然后最终获取互斥体以顺序写入稀疏数组数据结构来生成CSR稀疏矩阵。这大致是每个线程的伪代码:

read parquet data
get list of nonzero values
acquire mutex
append nonzero values to sparse array (basically memcpy)
release mutex
repeat
代码的速度不会随着CPU的增加而提高,因此我怀疑互斥争用是一个瓶颈。因此,我想尝试将互斥体替换为稀疏数组中的原子“offset”变量,这样我就可以执行以下操作:

fn推送(&self,rhs:&self,offset:&AtomicU64)->MyResult{
让old=offset.fetch\u add(rhs.data.0.len()+(1>32);
设indptr=nnz.try_-into()?+rhs.data.0.len().try_-into()?;
让range=nnz..nnz+rhs.data.0.len();
self.data[range]。从\u切片复制\u(&rhs.data.0);
self.index[range]。从\u切片复制\u(&rhs.index.0);
self.indptr[m]=indptr;
self.y[m]=rhs.y.0[0];
好(())
}

也就是说,我希望每个线程首先将指针原子地更新到稀疏数组中,然后写入前面的数据。问题是,数据是一个不可变的引用
&
(为了将它传递给每个线程),我需要一个可变的引用
&mut
(为了更新它).阅读类似的问题和生锈的文档似乎你不能像在C中那样完成这个简单的任务,但没有提供替代方案,这非常令人恼火。

我只真正阅读了标题。但这是否归结为,例如,是否可以在一个线程中分配
0..9
,然后在第二个线程中分配
10..19
,等等?不完全是这样,因为范围是动态的,即每个线程都在读取动态的数据数组,基本上我想连接它们。你提前知道数组的最终大小吗?如果你不知道,这会变得非常棘手,因为每当你尝试增加数组时,它可能需要重新分配到不同的位置。链表LD是一个更好的匹配,但可能有坏的性能。你会考虑至少等到所有的数据被处理并准备好连接,所以你可以计算最后的长度吗?我知道整个数组的最终长度,即稀疏矩阵中的非零元素的数量,所以重新分配不是问题。但是我不知道如何。在我从并行线程读取的每一行数据中都有许多非零元素。我没有看到任何原语能让你一直做到这一点,但Rust的一个好处是,如果一个原语不存在,你可以自己构建一个。这是一个使用
不安全的
来组合一些我认为对你的情况有效的东西的好方法。Eve
mod vec_filler
中的rything可以放入自己的文件(或者可能放入自己的板条箱)使用原子而不是互斥锁肯定有办法,但它应该可以减少争用。我只是真正阅读了标题。但这可以归结为,例如,是否可以在一个线程中分配
0..9
,然后在第二个线程中分配
10..19
,等等?不完全可以,因为范围是动态的,即每个线程都是读取的在动态数组中插入数据,基本上我想连接它们。你提前知道数组的最终大小吗?如果你不知道,这会变得非常棘手,因为每当你尝试增加数组时,它可能需要重新分配到不同的位置。链表会更合适,但性能可能会很差。你会考虑吗至少要等到所有的数据都被处理并准备好连接,这样你才能计算出最终的长度?我知道整个数组的最终长度,即稀疏矩阵中非零元素的数量,所以重新分配不是问题。但是我不知道我从p读取的每行数据中有多少非零元素平行线程。我没有看到任何原语能让你一直走到这一步,但生锈的一个好处是,如果一个原语不存在,你可以自己构建一个。这是一个使用
不安全的
来组合一些我认为对你的情况有效的东西的好方法。mod vec_filler
中的所有内容都可以放在自己的文件中(或者,可能是它自己的板条箱)。确实有办法使用原子而不是互斥,但它应该减少争用。