我正在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
}
这需要两个向量a
和b
(具有相同的长度),并进行逐元素乘法(向量a
的值1与向量{{的值1)相乘1}},并将其添加到向量b
的值2以及向量a
的值2中,依此类推...)。
有没有更有效的方法?如果是,怎么办?
答案 0 :(得分:3)
这并不是一个全面的一般答案,但我想分享一些代码。
您的实现看起来很像我会做的事情,除非我知道这是我应用程序的瓶颈。然后,我将研究更深奥的方法(也许是SIMD)。
也就是说,您可以考虑更改函数以采用切片引用。这样,您可以传递Vec
或数组:
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]));
}
另请参阅:
答案 1 :(得分:1)
我用rayon
和packed_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。我希望这有帮助。