如何获取Rayon的chunk索引par_chunks_mut

How to obtain the chunk index in Rayon's par_chunks_mut

我有一些数据,我想处理它并用它来填充一个已经存在的数组。例如假设我想将每个值重复 4 次 (playground):

use rayon::prelude::*; // 1.3.0

fn main() {
    let input = vec![4, 7, 2, 3, 5, 8];

    // This already exists.
    let mut output = vec![0; input.len() * 4];

    output.par_chunks_mut(4).for_each(|slice| {
        for x in slice.iter_mut() {
            *x = input[?];
        }
    });
}

这几乎可以工作,但 Rayon 没有将块索引传递给我,所以我无法在 input[?] 中放入任何内容。有没有有效的解决方案?

最简单的方法就是完全避免索引。对于这个例子,我们可以只压缩迭代器:

use rayon::prelude::*; // 1.3.0

fn main() {
    let input = vec![4, 7, 2, 3, 5, 8];
    let mut output = vec![0; input.len() * 4];

    // Can also use `.zip(&input)` if you don't want to give up ownership
    output.par_chunks_mut(4).zip(input).for_each(|(o, i)| {
        for o in o {
            *o = i
        }
    });

    println!("{:?}", output)
}

对于传统的迭代器,这种实现方式是有益的,因为它避免了不必要的边界检查,否则这些边界检查将由迭代器处理。我不确定 Rayon 从完全相同的事情中受益,但我也看不出有任何理由不会。

Rayon 为它的大多数迭代器提供了一个 enumerate() 函数,其工作方式与非并行迭代器类似:

let input = vec![4, 7, 2, 3, 5, 8];
let mut output = vec![0; input.len() * 4];

output.par_chunks_mut(4).enumerate().for_each(|(i, slice)| {
    for x in slice.iter_mut() {
        *x = input[i];
    }
});