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