首页 > 解决方案 > 我想制作 rust 的 for 语句多线程

问题描述

我想将以下功能更改为并行处理。

fn cal_v(c: &Array3<f32>, dt: f32) -> Array3<f32> {
  let mut v: Array3<f32> = Array::zeros(c.raw_dim());
  for time in 1..c.shape()[0] {
    let before = c.slice(s![time-1, .., ..]).to_owned();
    let now = c.slice(s![time, .., ..]).to_owned();
    let now_v = (before - now) / dt;
    v.slice_mut(s![time, .., ..]).assign(&now_v);
  }
  v
}

函数 c 是一个 3 维数组,其中第一维是时间索引,第二维是粒子数索引,第三维是 x,y,z。就个人而言,我想学习如何编写多线程代码,我想学习如何使其成为多线程,所以我想做for time in 1..c.shape()[0]多线程的部分。我相信这个过程可以并行化或异步化,因为在任何索引的过程中都没有依赖关系for。写这个的最好方法是什么?

我使用的编译器版本是1.51.0. 我正在使用的库版本是ndarray(0.14.0).

标签: multithreadingrust

解决方案


并行化迭代的最简单方法是只使用rayon,这基本上是它的生计。您必须将循环转换为更实用的样式(for_each用于最终循环体),但完成par_iter()后将“神奇地”将工作分配到其线程池中。

有一个问题我不太清楚,因为您没有提供任何代码:

v.slice_mut(s![time, .., ..]).assign(&now_v);

是所有项目之间的硬顺序依赖关系,我不知道s宏的作用,所以它可能可行,也可能不可行。如果每个从(或至少不重叠的插槽)time产生一个插槽,您将能够将迭代器放在一起,以便每个迭代都有一个独立于所有其他迭代的“源”和一个“目标”,否则你会有一个输出中的顺序阻塞点,这不是人造丝很好地支持的。vzip


推荐阅读