【问题标题】:What is the fastest way to calculate the dot product of two f64 vectors in Rust?在 Rust 中计算两个 f64 向量的点积的最快方法是什么?
【发布时间】:2019-01-03 19:25:45
【问题描述】:

我正在用 Rust 编写一个神经网络的实现,并试图计算两个矩阵的点积。我有以下代码:

fn dot_product(a: Vec<f64>, b: Vec<f64>) -> f64 {
    // Calculate the dot product of two vectors.
    asserteq!(a.len(), b.len());
    let mut product: f64;
    for i in 0..a.len() {
        product += a[i] * b[i];
    }
    product
}

这需要两个向量,ab(长度相同)并执行逐元素乘法(将向量 a 的值 1 与向量 b 的值 1 相乘并将其添加到值向量 a 的 2 和向量 b 的值为 2 等等......)。

有没有更有效的方法,如果有,怎么做?

【问题讨论】:

  • 对我来说看起来不错。我会一直使用它,直到你确信它是一个瓶颈。如果您已经确定需要尽可能快的速度,也许可以查看SIMD
  • 您可以使用迭代器在一行中完成,例如a.into_iter().zip(b).map(|(a, b)| a*b).sum()。但我希望它会相当快,而不是明显更快(或更慢)。

标签: rust


【解决方案1】:

这并不是一个全面的一般答案,但我想分享一些代码。

除非我知道这是我的应用程序的瓶颈,否则您的实现看起来很像我会做的。然后我会研究更深奥的方法(可能是SIMD)。

也就是说,您可能会考虑将您的函数改为采用切片引用。这样你就可以传递Vecs 或数组:

fn dot_product(a: &[f64], b: &[f64]) -> f64 {
    // Calculate the dot product of two vectors. 
    assert_eq!(a.len(), b.len()); 
    let mut product = 0.0;
    for i in 0..a.len() {
        product += a[i] * b[i];
    }
    product
}

fn main() {
    println!("{}", dot_product(&[1.0,2.0], &[3.0,4.0]));
    println!("{}", dot_product(&vec![1.0,2.0], &vec![3.0,4.0]));
}

另见:

【讨论】:

    【解决方案2】:

    我使用rayonpacked_simd 来计算点积和 找到了一种比英特尔 MKL 更快的方法:

    extern crate packed_simd;
    extern crate rayon;
    extern crate time;
    
    use packed_simd::f64x4;
    use packed_simd::f64x8;
    use rayon::prelude::*;
    use std::vec::Vec;
    
    fn main() {
        let n = 100000000;
        let x: Vec<f64> = vec![0.2; n];
        let y: Vec<f64> = vec![0.1; n];
    
        let res: f64 = x
            .par_chunks(8)
            .map(f64x8::from_slice_unaligned)
            .zip(y.par_chunks(8).map(f64x8::from_slice_unaligned))
            .map(|(a, b)| a * b)
            .sum::<f64x8>()
            .sum();
        println!("res: {}", res);
    }
    

    This code in my Github。我希望这有帮助。

    【讨论】:

    • 不需要use std::vec::Vec;;这是前奏曲的一部分。为什么时间箱会在这里?您能否将其与 OPs 代码和其他答案的性能进行比较?为什么选择unaligned
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    • 2015-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多