Skip to main content

TransferStageProfile

Struct TransferStageProfile 

Source
pub struct TransferStageProfile {
    pub calls: u64,
    pub transfers: u64,
    pub validation: Duration,
    pub setup: Duration,
    pub submit: Duration,
    pub wait_write: Duration,
    pub wait_read: Duration,
    pub decode_copy: Duration,
}

Fields§

§calls: u64§transfers: u64§validation: Duration§setup: Duration§submit: Duration§wait_write: Duration§wait_read: Duration§decode_copy: Duration

Implementations§

Source§

impl TransferStageProfile

Source

pub fn merge(&mut self, other: &Self)

Examples found in repository?
examples/bench_transfer.rs (line 170)
147fn run_device_bench(options: &Options) -> Result<(), Box<dyn Error>> {
148    let mut board = Board::open_with_transport(options.transport)?;
149    let max_cycles_per_transfer = usize::from(board.config().fifo_size_words()) / WORDS_PER_CYCLE;
150    let mut io = board.configure_io(&IoConfig {
151        clock_high_delay: options.clock_high_delay,
152        clock_low_delay: options.clock_low_delay,
153        ..IoConfig::default()
154    })?;
155
156    if options.window == 0 {
157        return Err("window must be at least 1".into());
158    }
159
160    let template = vec![0x1234u16; options.words];
161    let mut rx = vec![0u16; options.words];
162    let mut outputs = vec![vec![0u16; options.words]; options.window];
163    let mut stage_profile = TransferStageProfile::default();
164
165    let started = Instant::now();
166    if options.window == 1 {
167        if options.profile_stages {
168            for _ in 0..options.iterations {
169                let profile = io.transfer_profiled_into(&template, &mut rx)?;
170                stage_profile.merge(&profile);
171            }
172        } else {
173            for _ in 0..options.iterations {
174                io.transfer(&template, &mut rx)?;
175            }
176        }
177    } else {
178        let mut window = io.transfer_window(options.words, options.window)?;
179        let initial = options.iterations.min(options.window);
180        for _ in 0..initial {
181            if options.profile_stages {
182                let profile = window.submit_profiled(&template)?;
183                stage_profile.merge(&profile);
184            } else {
185                window.submit(&template)?;
186            }
187        }
188
189        let mut submitted = initial;
190        let mut completed = 0usize;
191        while completed < options.iterations {
192            let output = outputs[completed % options.window].as_mut_slice();
193            if options.profile_stages {
194                let profile = window.receive_into_profiled(output)?;
195                stage_profile.merge(&profile);
196            } else {
197                window.receive_into(output)?;
198            }
199            completed += 1;
200
201            if submitted < options.iterations {
202                if options.profile_stages {
203                    let profile = window.submit_profiled(&template)?;
204                    stage_profile.merge(&profile);
205                } else {
206                    window.submit(&template)?;
207                }
208                submitted += 1;
209            }
210        }
211    }
212    let elapsed = started.elapsed();
213    io.finish()?;
214
215    print_summary(
216        "device",
217        options.words,
218        options.iterations,
219        elapsed,
220        Some(max_cycles_per_transfer),
221    );
222    if options.profile_stages {
223        print_stage_profile(&stage_profile, elapsed);
224    }
225    Ok(())
226}
Source

pub fn total_duration(&self) -> Duration

Examples found in repository?
examples/bench_transfer.rs (line 258)
257fn print_stage_profile(profile: &TransferStageProfile, elapsed: Duration) {
258    let accounted = profile.total_duration();
259    let elapsed_secs = elapsed.as_secs_f64().max(f64::MIN_POSITIVE);
260    let accounted_secs = accounted.as_secs_f64().max(f64::MIN_POSITIVE);
261    let transfers = profile.transfers.max(1);
262
263    println!(
264        "profile calls={} transfers={} accounted={:?} wall={:?} unaccounted={:?}",
265        profile.calls,
266        profile.transfers,
267        accounted,
268        elapsed,
269        elapsed.saturating_sub(accounted),
270    );
271
272    for (stage, duration) in [
273        ("validation", profile.validation),
274        ("setup", profile.setup),
275        ("submit", profile.submit),
276        ("wait_write", profile.wait_write),
277        ("wait_read", profile.wait_read),
278        ("decode_copy", profile.decode_copy),
279    ] {
280        let pct_of_accounted = duration.as_secs_f64() * 100.0 / accounted_secs;
281        let pct_of_wall = duration.as_secs_f64() * 100.0 / elapsed_secs;
282        let avg_us_per_transfer = duration.as_secs_f64() * 1_000_000.0 / transfers as f64;
283        println!(
284            "stage={stage} duration={duration:?} pct_accounted={pct_of_accounted:.2} pct_wall={pct_of_wall:.2} avg_us_per_transfer={avg_us_per_transfer:.3}"
285        );
286    }
287}

Trait Implementations§

Source§

impl Clone for TransferStageProfile

Source§

fn clone(&self) -> TransferStageProfile

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TransferStageProfile

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for TransferStageProfile

Source§

fn default() -> TransferStageProfile

Returns the “default value” for a type. Read more
Source§

impl PartialEq for TransferStageProfile

Source§

fn eq(&self, other: &TransferStageProfile) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for TransferStageProfile

Source§

impl StructuralPartialEq for TransferStageProfile

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.