diff --git a/_drafts/libm_vs_micromath_speed_comparison.qmd b/_drafts/libm_vs_micromath_speed_comparison.qmd deleted file mode 100644 index 100c982..0000000 --- a/_drafts/libm_vs_micromath_speed_comparison.qmd +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: "Rust: libm vs micromath speed comparison" -author: "James Pace" -date: "2024/01/16" ---- - - diff --git a/_drafts/powf_is_slow.md b/_drafts/powf_is_slow.md deleted file mode 100644 index c9baf83..0000000 --- a/_drafts/powf_is_slow.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: "Rust: powf is slow" -author: "James Pace" -date: "2024/01/18" ---- - -I'm currently working on my motion planner on a microcontroller project and -was looking at switching from [libm][libm] to [micromath][micromath] as the -library I use for standard math operations. -For context, in Rust, normal math operations (like absolute value and square -root for floats) are provided as part of the standard library (called `std`). -The standard library is not available in environments that don't have a backing -operating system. -Crates than run in those environments thus can't use `std`, which is called being -`no_std`. -A lot of functions that are in `std` are actually in two other crates, `core` or `alloc` -which can be used in `no_std` environments. -The normal math functions aren't one of them, and therefore a different library has to be -used. - -My intitial implementation of the planner used `libm` (largely because I found it first), -and when I later found `micromath` I wanted to do some profiling comparisons to see which -one was faster. -I'm going to make a separate blog post with statistics from the profiling, but I wanted to -write a quick article today talking about `powf`. - -One of the operations my planner does a lot is find the distance between two things. -My initial implementation did something like -```rust -fn distance(point1: &Point, point2: &Point) -> f32 { - let squared_dist = powf((point2.x - point1.x), 2.0) + powf((point2.y - point1.y), 2.0); - sqrt(squared_dist) -} -``` -which works fine. - -When I was profiling I switched to: -```rust -fn distance(point1: &Point, point2: &Point) -> f32 { - let squared_dist = powf((point2.x - point1.x), 2.0) + powf((point2.y - point1.y), 2.0); - sqrt(squared_dist) -} -``` -which was noticeably faster for both `libm` and `micromath` particularly on the `microbit` -that I was using for profiling. - -## Does this replicate for `std::powf`? - -Not when building with `--release`. [^release-rant] - - - -## How much faster? - -[^release-rant]: As an aside, I think I'm going to switch to using `--release` when building rust code - all the time. The optimizations help a ton, to the extent I would never "use" software - not built with `--release` and extrapolating performance, even experientially, from - binaries built with the `dev` profile is just not transferrable at all. - -[libm]: https://github.com/rust-lang/libm -[micromath]: https://github.com/tarcieri/micromath diff --git a/posts/powf_is_slow.md b/posts/powf_is_slow.md new file mode 100644 index 0000000..a5f2aaf --- /dev/null +++ b/posts/powf_is_slow.md @@ -0,0 +1,48 @@ +--- +title: "Rust: powf is slow" +author: "James Pace" +date: "2024/01/31" +--- + +I'm currently working on a project in Rust which does a lot of math on +a microcontroller. +In Rust, normal math operations (like absolute value and square +root for floats) are provided as part of the standard library (called `std`), +which is not available for the microcontroller I'm using. +Thus, alternate libraries have to be used. + +The two major ones I've found (and which I need to do a detailed comparison +of) are [micromath][micromath] and [libm][libm]. +For now, I've been using `libm`, mainly because its the first one I found. + +One of the operations my project does a lot is find the distance between two points. +My initial implementation did something like +```rust +fn distance(point1: &Point, point2: &Point) -> f32 { + let squared_dist = libm::powf((point2.x - point1.x), 2.0) + libm::powf((point2.y - point1.y), 2.0); + sqrt(squared_dist) +} +``` + +While doing some profiling, I switched to +```rust +fn distance(point1: &Point, point2: &Point) -> f32 { + let x_dist = point2.x - point1.x; + let y_dist = point2.y - point1.y; + + let squared_dist = x_dist*x_dist + y_dist*y_dist; + libm::sqrt(squared_dist) +} +``` +which was significantly faster, especially on the `microbit` I was running the code on for +profiling. + +Out of curiousity, I tried doing the same thing, but on my laptop using `std::powf` instead +of `libm::powf`. + +When compiling with the default optimization level (`-O3`), I saw a similar performance +increase, but not when I switched to compiling with `--release`, which I found interesting, +and which underscores the importance of building in `--release` which shipping Rust binaries. + +[libm]: https://github.com/rust-lang/libm +[micromath]: https://github.com/tarcieri/micromath