0

我有一个函数,它获取一个数组、开始索引和结束索引。我想返回这个数组的最大元素。依次它工作正常。但我不知道如何将其转换为并行工作。所以你能告诉我怎么做吗?我一直在尝试 Rayon 的 for_each() 但总是遇到一些错误。转换后的函数会是什么样子?

pub fn search_max(array: &[f32], start: i32, end: i32)-> f32 {
    let mut maximum: f32 = A[p as usize];
    let iter: usize = start as usize + 1;
    for iter in iter..end as usize{
        if maximum < array[iter] {
            maximum = array[iter];
        }
    }   
    maximum
}
4

1 回答 1

2

您目前拥有所谓的命令式代码;不经过函数式风格就不能直接改成并行:

pub fn search_max(array: &[f32], start: i32, end: i32) -> f32 {
    let sub_array: &[f32] = &array[start as usize..end as usize];
    *sub_array.iter().max().unwrap()
}

我们使用该max方法来获取迭代器产生的最大值。这不起作用,因为f32不能保证很好地订购。我们将使用max_by闭包代替:

pub fn search_max(array: &[f32], start: i32, end: i32) -> f32 {
    let sub_array: &[f32] = &array[start as usize..end as usize];

    *    // This results in &f32, so we must dereference it
    sub_array.iter() // Create the iterator over references to the items
    .max_by(
        |x, y| x.partial_cmp(y).unwrap() // https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html#tymethod.partial_cmp
    ).unwrap() // There could possibly be no items! So we get an `Option<&f32>` instead.
}

在大多数情况下,rayon'sParallelIterator是常规迭代器的替代品,所以我们看到的任何地方都.iter更改为.par_iter

use rayon::prelude::*;

pub fn search_max(array: &[f32], start: i32, end: i32) -> f32 {
    let sub_array: &[f32] = &array[start as usize..end as usize];
    *sub_array.par_iter().max_by(|x, y| x.partial_cmp(y).unwrap()).unwrap()
}

操场


如果您正在寻找最惯用的版本:

pub fn search_max(slice: &'_ [f32], start: usize, end: usize) -> f32 {
    *slice[start..end].par_iter().reduce(
        || &slice[start], // This is an iterator over &'_ f32
        |a, b| if a > b { a } else { b },
    )
}

操场

于 2019-12-05T01:46:41.343 回答