Skip to content

Commit

Permalink
swrenderer: make sure small functions in fixed point are inlined
Browse files Browse the repository at this point in the history
`cargo bench -p printerdemo_mcu`

Before
```
bench                fastest       │ slowest       │ median        │ mean          │ samples │ iters
├─ full                            │               │               │               │         │
│  ├─ Rgb565Pixel    2.919 ms      │ 8.155 ms      │ 4.279 ms      │ 4.326 ms      │ 100     │ 100
│  ╰─ Rgb<u8>        6.139 ms      │ 10.49 ms      │ 7.729 ms      │ 7.826 ms      │ 100     │ 100
╰─ render_only                     │               │               │               │         │
   ├─ Rgb565Pixel                  │               │               │               │         │
   │  ├─ FullBuffer  1.439 ms      │ 4.138 ms      │ 1.597 ms      │ 1.635 ms      │ 100     │ 100
   │  ╰─ LineByLine  1.576 ms      │ 1.765 ms      │ 1.636 ms      │ 1.642 ms      │ 100     │ 100
   ╰─ Rgb<u8>                      │               │               │               │         │
      ├─ FullBuffer  2.016 ms      │ 2.872 ms      │ 2.111 ms      │ 2.128 ms      │ 100     │ 100
      ╰─ LineByLine  2.122 ms      │ 2.995 ms      │ 2.21 ms       │ 2.245 ms      │ 100     │ 100
```

After
```
bench                fastest       │ slowest       │ median        │ mean          │ samples │ iters
├─ full                            │               │               │               │         │
│  ├─ Rgb565Pixel    2.187 ms      │ 4.913 ms      │ 3.48 ms       │ 3.505 ms      │ 100     │ 100
│  ╰─ Rgb<u8>        5.489 ms      │ 8.193 ms      │ 6.713 ms      │ 6.723 ms      │ 100     │ 100
╰─ render_only                     │               │               │               │         │
   ├─ Rgb565Pixel                  │               │               │               │         │
   │  ├─ FullBuffer  1.105 ms      │ 1.932 ms      │ 1.225 ms      │ 1.278 ms      │ 100     │ 100
   │  ╰─ LineByLine  1.188 ms      │ 2.052 ms      │ 1.289 ms      │ 1.352 ms      │ 100     │ 100
   ╰─ Rgb<u8>                      │               │               │               │         │
      ├─ FullBuffer  1.505 ms      │ 2.643 ms      │ 1.599 ms      │ 1.669 ms      │ 100     │ 100
      ╰─ LineByLine  1.539 ms      │ 2.058 ms      │ 1.641 ms      │ 1.652 ms      │ 100     │ 100
```
  • Loading branch information
ogoffart committed Mar 6, 2025
1 parent 7da7e10 commit 754a6bf
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
6 changes: 6 additions & 0 deletions internal/core/software_renderer/draw_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,24 +327,30 @@ pub(super) fn draw_rounded_rectangle_line(
impl Shifted {
const ONE: Self = Shifted(1 << 4);
#[track_caller]
#[inline]
pub fn new(value: impl TryInto<u32> + core::fmt::Debug + Copy) -> Self {
Self(value.try_into().unwrap_or_else(|_| panic!("Overflow {value:?}")) << 4)
}
#[inline(always)]
pub fn floor(self) -> u32 {
self.0 >> 4
}
#[inline(always)]
pub fn ceil(self) -> u32 {
(self.0 + Self::ONE.0 - 1) >> 4
}
#[inline(always)]
pub fn saturating_sub(self, other: Self) -> Self {
Self(self.0.saturating_sub(other.0))
}
#[inline(always)]
pub fn sqrt(self) -> Self {
Self(self.0.integer_sqrt())
}
}
impl core::ops::Mul for Shifted {
type Output = Shifted;
#[inline(always)]
fn mul(self, rhs: Self) -> Self::Output {
Self(self.0 * rhs.0)
}
Expand Down
16 changes: 16 additions & 0 deletions internal/core/software_renderer/fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ impl<
> Fixed<T, SHIFT>
{
/// Create a fixed point from an integer value
#[inline(always)]
pub fn from_integer(value: T) -> Self {
Self(value << SHIFT)
}

/// Get the integer part of the fixed point value
#[inline(always)]
pub fn truncate(self) -> T {
self.0 >> SHIFT
}

/// Return the fractional part of the fixed point value
#[inline(always)]
pub fn fract(self) -> u8
where
T: num_traits::AsPrimitive<u8>,
Expand All @@ -37,6 +40,7 @@ impl<
}
}

#[inline(always)]
pub fn from_fixed<
T2: core::ops::Shl<usize, Output = T2> + core::ops::Shr<usize, Output = T2> + Into<T>,
const SHIFT2: usize,
Expand All @@ -50,6 +54,7 @@ impl<
Self((value.0 >> (SHIFT2 - SHIFT)).into())
}
}
#[inline(always)]
pub fn try_from_fixed<
T2: core::ops::Shl<usize, Output = T2> + core::ops::Shr<usize, Output = T2> + TryInto<T>,
const SHIFT2: usize,
Expand All @@ -64,10 +69,12 @@ impl<
})
}

#[inline(always)]
pub fn from_fraction(numerator: T, denominator: T) -> Self {
Self((numerator << SHIFT) / denominator)
}

#[inline(always)]
pub(crate) fn from_f32(value: f32) -> Option<Self>
where
T: num_traits::FromPrimitive,
Expand All @@ -78,60 +85,69 @@ impl<

impl<T: core::ops::Add<Output = T>, const SHIFT: usize> core::ops::Add for Fixed<T, SHIFT> {
type Output = Self;
#[inline(always)]
fn add(self, rhs: Self) -> Self::Output {
Self(self.0.add(rhs.0))
}
}

impl<T: core::ops::Sub<Output = T>, const SHIFT: usize> core::ops::Sub for Fixed<T, SHIFT> {
type Output = Self;
#[inline(always)]
fn sub(self, rhs: Self) -> Self::Output {
Self(self.0.sub(rhs.0))
}
}

impl<T: core::ops::AddAssign, const SHIFT: usize> core::ops::AddAssign for Fixed<T, SHIFT> {
#[inline(always)]
fn add_assign(&mut self, rhs: Self) {
self.0.add_assign(rhs.0)
}
}

impl<T: core::ops::SubAssign, const SHIFT: usize> core::ops::SubAssign for Fixed<T, SHIFT> {
#[inline(always)]
fn sub_assign(&mut self, rhs: Self) {
self.0.sub_assign(rhs.0)
}
}

impl<T: core::ops::Mul<Output = T>, const SHIFT: usize> core::ops::Mul<T> for Fixed<T, SHIFT> {
type Output = Self;
#[inline(always)]
fn mul(self, rhs: T) -> Self::Output {
Self(self.0.mul(rhs))
}
}

impl<T: core::ops::Neg<Output = T>, const SHIFT: usize> core::ops::Neg for Fixed<T, SHIFT> {
type Output = Self;
#[inline(always)]
fn neg(self) -> Self::Output {
Self(-self.0)
}
}

impl<T: core::ops::Div<Output = T>, const SHIFT: usize> core::ops::Div for Fixed<T, SHIFT> {
type Output = T;
#[inline(always)]
fn div(self, rhs: Self) -> Self::Output {
self.0 / rhs.0
}
}

impl<T: core::ops::Rem<Output = T>, const SHIFT: usize> core::ops::Rem for Fixed<T, SHIFT> {
type Output = Self;
#[inline(always)]
fn rem(self, rhs: Self) -> Self::Output {
Self(self.0 % rhs.0)
}
}

impl<T: core::ops::Div<Output = T>, const SHIFT: usize> core::ops::Div<T> for Fixed<T, SHIFT> {
type Output = Self;
#[inline(always)]
fn div(self, rhs: T) -> Self::Output {
Self(self.0 / rhs)
}
Expand Down

0 comments on commit 754a6bf

Please sign in to comment.