计算Rust中两个f64向量的点积的最快方法是什么?
我正在写一个Rust中神经网络的实现,并试图计算两个矩阵的点积。我有以下代码:计算Rust中两个f64向量的点积的最快方法是什么?,rust,Rust,我正在写一个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() { pro
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
}
fn dot_乘积(a:Vec,b:Vec)->f64{
//计算两个向量的点积。
asserteq!(a.len(),b.len());
让mut产品:f64;
对于0..a.len()中的i{
产品+=a[i]*b[i];
}
产品
}
这取两个向量,a
和b
(长度相同)并执行元素相乘(将向量a
的值1与向量b
的值1相乘,并将其与向量a
的值2和向量b
的值2相加,以此类推……)
有没有更有效的方法来实现这一点,如果有,如何实现?这并不是一个全面的一般性答案,但我想分享一些代码 除非我知道这是我的应用程序中的瓶颈,否则您的实现看起来很像我将要做的。然后我会研究更深奥的方法(也许)
这样说,你可以考虑改变你的函数来代替切片引用。这样,您可以传递
Vec
s或数组:
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]));
}
另见:
这样说,你可以考虑改变你的函数来代替切片引用。这样,您可以传递
Vec
s或数组:
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]));
}
另见:
人造丝
和压缩的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);
}
extern板条箱包装\u simd;
外部板条箱人造丝;
外置板条箱时间;
使用压缩单指令多数据::f64x4;
使用压缩单指令多数据::f64x8;
使用人造丝::前奏::*;
使用std::vec::vec;
fn main(){
设n=100000000;
设x:Vec=Vec![0.2;n];
设y:Vec=Vec![0.1;n];
设res:f64=x
.par_块(8)
.map(f64x8::从切片到未对齐)
.zip(y.par_chunks(8.map)(f64x8::from_slice_unaligned))
.地图(|(a,b)| a*b)
.sum::()
.sum();
println!(“res:{}”,res);
}
。我希望这有帮助 我使用
rayon
和packed\u 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);
}
extern板条箱包装\u simd;
外部板条箱人造丝;
外置板条箱时间;
使用压缩单指令多数据::f64x4;
使用压缩单指令多数据::f64x8;
使用人造丝::前奏::*;
使用std::vec::vec;
fn main(){
设n=100000000;
设x:Vec=Vec![0.2;n];
设y:Vec=Vec![0.1;n];
设res:f64=x
.par_块(8)
.map(f64x8::从切片到未对齐)
.zip(y.par_chunks(8.map)(f64x8::from_slice_unaligned))
.地图(|(a,b)| a*b)
.sum::()
.sum();
println!(“res:{}”,res);
}
。我希望这有帮助 我觉得不错。我会一直使用它,直到你确信它是一个瓶颈。如果您已经确定需要尽可能快的速度,那么可以研究一下?您可以使用迭代器在一行中完成,如
a.into_iter().zip(b).map(|(a,b)| a*b).sum()
。但我希望它会相当快,而不是明显快(或慢),我觉得很好。我会一直使用它,直到你确信它是一个瓶颈。如果您已经确定需要尽可能快的速度,那么可以研究一下?您可以使用迭代器在一行中完成,如a.into_iter().zip(b).map(|(a,b)| a*b).sum()
。但我希望它会相当快,而不是明显快(或慢)代码>;这是序曲的一部分。为什么时间箱在这里?你能把这与OPs代码的性能和另一个答案进行比较吗?为什么选择未对齐的
?不需要使用std::vec::vec代码>;这是序曲的一部分。为什么时间箱在这里?你能把这与OPs代码的性能和另一个答案进行比较吗?为什么选择未对齐的
?