From 5cd423bb202e4e4c4229e3036e36f5bbc5278e3f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 8 Feb 2016 12:55:06 -0800 Subject: [PATCH] Fast log2 implementation. Big improvement in code size (2034 bytes!). Baseband FFT (idle) thread CPU cut in half. --- firmware/common/utility.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/firmware/common/utility.cpp b/firmware/common/utility.cpp index 5162bcd6..715a0496 100644 --- a/firmware/common/utility.cpp +++ b/firmware/common/utility.cpp @@ -22,7 +22,6 @@ #include "utility.hpp" #include -#include #if 0 uint32_t gcd(const uint32_t u, const uint32_t v) { @@ -60,6 +59,20 @@ uint32_t gcd(const uint32_t u, const uint32_t v) { } #endif +static float fast_log2(const float val) { + // Thank you Stack Overflow! + // http://stackoverflow.com/questions/9411823/fast-log2float-x-implementation-c + union { + float val; + int32_t x; + } u = { val }; + float log_2 = (((u.x >> 23) & 255) - 128); + u.x &= ~(255 << 23); + u.x += (127 << 23); + log_2 += ((-0.34484843f) * u.val + 2.02466578f) * u.val - 0.67487759f; + return log_2; +} + float complex16_mag_squared_to_dbv_norm(const float c16_mag_squared) { constexpr float input_component_max = 32768; constexpr float mag2_max = (input_component_max * input_component_max) * 2; @@ -68,7 +81,7 @@ float complex16_mag_squared_to_dbv_norm(const float c16_mag_squared) { constexpr float log2_log10_factor = std::log10(2.0f); constexpr float log10_dbv_factor = 20.0f; constexpr float mag2_to_db_factor = log_mag2_mag_factor * log2_log10_factor * log10_dbv_factor; - return (std::log2(c16_mag_squared) - mag2_log2_max) * mag2_to_db_factor; + return (fast_log2(c16_mag_squared) - mag2_log2_max) * mag2_to_db_factor; } /* GCD implementation derived from recursive implementation at