मैं जंग में एक तंत्रिका नेटवर्क का कार्यान्वयन लिख रहा हूं और दो मैट्रिक्स के डॉट उत्पाद की गणना करने की कोशिश कर रहा हूं। मेरे पास निम्न कोड है:

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 को वेक्टर b के मान से गुणा करता है। और इसे सदिश a के मान 2 और वेक्टर b के मान 2 और इसी तरह...) में जोड़ते हुए।

क्या ऐसा करने का एक अधिक कुशल तरीका है, और यदि हां, तो कैसे?

1
Teymour Aldridge 3 जिंदा 2019, 22:25

2 जवाब

सबसे बढ़िया उत्तर

यह एक व्यापक सामान्य उत्तर के रूप में नहीं है, लेकिन मैं थोड़ा कोड साझा करना चाहता था।

आपका कार्यान्वयन बहुत कुछ वैसा ही दिखता है जैसा मैं करूँगा जब तक मुझे पता नहीं था कि यह मेरे आवेदन में बाधा थी। फिर मैं और अधिक गूढ़ तरीकों पर गौर करूंगा (शायद 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]));
}

यह सभी देखें:

3
Shepmaster 20 मई 2019, 19:28

मैंने डॉट उत्पाद की गणना करने के लिए rayon और packed_simd का उपयोग किया और इंटेल एमकेएल से तेज होने का एक तरीका मिला:

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);
}

यह कोड मेरे Github में है। आशा है कि ये आपकी मदद करेगा।

1
Shepmaster 20 मई 2019, 19:25