diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-02-12 03:19:46 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-02-13 21:28:03 +0100 |
| commit | 640ddc948190fe9a24d6db616cb103d6a94f81f9 (patch) | |
| tree | bbfc7be8b4e88179e5519b6d64db4d75eb04b31b | |
| parent | eb922c4655db4b22acf808855e3bc003d3b8ba89 (diff) | |
time: optimize math by reducing fractions at compile time.
For example, `as_micros`, `from_micros` now are noops if tick rate is 1MHz.
| -rw-r--r-- | embassy/src/time/duration.rs | 10 | ||||
| -rw-r--r-- | embassy/src/time/instant.rs | 10 | ||||
| -rw-r--r-- | embassy/src/time/mod.rs | 11 |
3 files changed, 21 insertions, 10 deletions
diff --git a/embassy/src/time/duration.rs b/embassy/src/time/duration.rs index e196a00c7..47b413f48 100644 --- a/embassy/src/time/duration.rs +++ b/embassy/src/time/duration.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | use core::fmt; | 1 | use core::fmt; |
| 2 | use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; | 2 | use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; |
| 3 | 3 | ||
| 4 | use super::TICKS_PER_SECOND; | 4 | use super::{GCD_1K, GCD_1M, TICKS_PER_SECOND}; |
| 5 | 5 | ||
| 6 | #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] | 6 | #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] |
| 7 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 7 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| @@ -28,12 +28,12 @@ impl Duration { | |||
| 28 | 28 | ||
| 29 | /// Convert the `Duration` to milliseconds, rounding down. | 29 | /// Convert the `Duration` to milliseconds, rounding down. |
| 30 | pub const fn as_millis(&self) -> u64 { | 30 | pub const fn as_millis(&self) -> u64 { |
| 31 | self.ticks * 1000 / TICKS_PER_SECOND | 31 | self.ticks * (1000 / GCD_1K) / (TICKS_PER_SECOND / GCD_1K) |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | /// Convert the `Duration` to microseconds, rounding down. | 34 | /// Convert the `Duration` to microseconds, rounding down. |
| 35 | pub const fn as_micros(&self) -> u64 { | 35 | pub const fn as_micros(&self) -> u64 { |
| 36 | self.ticks * 1_000_000 / TICKS_PER_SECOND | 36 | self.ticks * (1_000_000 / GCD_1M) / (TICKS_PER_SECOND / GCD_1M) |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | /// Creates a duration from the specified number of clock ticks | 39 | /// Creates a duration from the specified number of clock ticks |
| @@ -51,7 +51,7 @@ impl Duration { | |||
| 51 | /// Creates a duration from the specified number of milliseconds | 51 | /// Creates a duration from the specified number of milliseconds |
| 52 | pub const fn from_millis(millis: u64) -> Duration { | 52 | pub const fn from_millis(millis: u64) -> Duration { |
| 53 | Duration { | 53 | Duration { |
| 54 | ticks: millis * TICKS_PER_SECOND / 1000, | 54 | ticks: millis * (TICKS_PER_SECOND / GCD_1K) / (1000 / GCD_1K), |
| 55 | } | 55 | } |
| 56 | } | 56 | } |
| 57 | 57 | ||
| @@ -59,7 +59,7 @@ impl Duration { | |||
| 59 | /// NOTE: Delays this small may be inaccurate. | 59 | /// NOTE: Delays this small may be inaccurate. |
| 60 | pub const fn from_micros(micros: u64) -> Duration { | 60 | pub const fn from_micros(micros: u64) -> Duration { |
| 61 | Duration { | 61 | Duration { |
| 62 | ticks: micros * TICKS_PER_SECOND / 1_000_000, | 62 | ticks: micros * (TICKS_PER_SECOND / GCD_1M) / (1_000_000 / GCD_1M), |
| 63 | } | 63 | } |
| 64 | } | 64 | } |
| 65 | 65 | ||
diff --git a/embassy/src/time/instant.rs b/embassy/src/time/instant.rs index aff83be20..71adbeb3f 100644 --- a/embassy/src/time/instant.rs +++ b/embassy/src/time/instant.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | use core::fmt; | 1 | use core::fmt; |
| 2 | use core::ops::{Add, AddAssign, Sub, SubAssign}; | 2 | use core::ops::{Add, AddAssign, Sub, SubAssign}; |
| 3 | 3 | ||
| 4 | use super::{driver, Duration, TICKS_PER_SECOND}; | 4 | use super::{driver, Duration, GCD_1K, GCD_1M, TICKS_PER_SECOND}; |
| 5 | 5 | ||
| 6 | #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] | 6 | #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] |
| 7 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 7 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| @@ -31,14 +31,14 @@ impl Instant { | |||
| 31 | /// Create an Instant from a microsecond count since system boot. | 31 | /// Create an Instant from a microsecond count since system boot. |
| 32 | pub const fn from_micros(micros: u64) -> Self { | 32 | pub const fn from_micros(micros: u64) -> Self { |
| 33 | Self { | 33 | Self { |
| 34 | ticks: micros * TICKS_PER_SECOND / 1_000_000, | 34 | ticks: micros * (TICKS_PER_SECOND / GCD_1M) / (1_000_000 / GCD_1M), |
| 35 | } | 35 | } |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | /// Create an Instant from a millisecond count since system boot. | 38 | /// Create an Instant from a millisecond count since system boot. |
| 39 | pub const fn from_millis(millis: u64) -> Self { | 39 | pub const fn from_millis(millis: u64) -> Self { |
| 40 | Self { | 40 | Self { |
| 41 | ticks: millis * TICKS_PER_SECOND / 1000, | 41 | ticks: millis * (TICKS_PER_SECOND / GCD_1K) / (1000 / GCD_1K), |
| 42 | } | 42 | } |
| 43 | } | 43 | } |
| 44 | 44 | ||
| @@ -61,12 +61,12 @@ impl Instant { | |||
| 61 | 61 | ||
| 62 | /// Milliseconds since system boot. | 62 | /// Milliseconds since system boot. |
| 63 | pub const fn as_millis(&self) -> u64 { | 63 | pub const fn as_millis(&self) -> u64 { |
| 64 | self.ticks * 1000 / TICKS_PER_SECOND | 64 | self.ticks * (1000 / GCD_1K) / (TICKS_PER_SECOND / GCD_1K) |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | /// Microseconds since system boot. | 67 | /// Microseconds since system boot. |
| 68 | pub const fn as_micros(&self) -> u64 { | 68 | pub const fn as_micros(&self) -> u64 { |
| 69 | self.ticks * 1_000_000 / TICKS_PER_SECOND | 69 | self.ticks * (1_000_000 / GCD_1M) / (TICKS_PER_SECOND / GCD_1M) |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | /// Duration between this Instant and another Instant | 72 | /// Duration between this Instant and another Instant |
diff --git a/embassy/src/time/mod.rs b/embassy/src/time/mod.rs index c8971bd13..ac84b8f8d 100644 --- a/embassy/src/time/mod.rs +++ b/embassy/src/time/mod.rs | |||
| @@ -75,3 +75,14 @@ const TPS: u64 = 1_000_000; | |||
| 75 | /// allow you to choose a tick rate with Cargo features of their own. You should not | 75 | /// allow you to choose a tick rate with Cargo features of their own. You should not |
| 76 | /// set the `time-tick-*` features for embassy yourself as an end user. | 76 | /// set the `time-tick-*` features for embassy yourself as an end user. |
| 77 | pub const TICKS_PER_SECOND: u64 = TPS; | 77 | pub const TICKS_PER_SECOND: u64 = TPS; |
| 78 | |||
| 79 | const fn gcd(a: u64, b: u64) -> u64 { | ||
| 80 | if b == 0 { | ||
| 81 | a | ||
| 82 | } else { | ||
| 83 | gcd(b, a % b) | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | pub(crate) const GCD_1K: u64 = gcd(TICKS_PER_SECOND, 1_000); | ||
| 88 | pub(crate) const GCD_1M: u64 = gcd(TICKS_PER_SECOND, 1_000_000); | ||
