From d9cbdaf1eda5a2116087149313b3005e7e0a57be Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Sun, 31 Dec 2023 11:44:43 -0800 Subject: libs/din: trivial optimizations din() is a hot path for modules/swab in particular. Barring any substantial changes to swab, which would probably make sense in the long-term, there's some low-hanging fruit in libs/din. Here smootherstep() has been made less general for a little perf boost. The way din uses smootherstep() doesn't need these bounds checks, nor does it need the caller-supplied edge values. Also the asserts() have been disabled in the hot path as they were mostly there for catching programmer errors and swab is already done. On my i7 x230 this takes swab from 44fps->54fps, so worthwhile, but swab is still painfully slow here. It's largely just a libs/din abuse module that was made to test libs/din, but turned out to look interesting enough to keep. --- src/libs/din/din.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/libs/din/din.c b/src/libs/din/din.c index b2c2823..aa71a2f 100644 --- a/src/libs/din/din.c +++ b/src/libs/din/din.c @@ -88,20 +88,7 @@ static inline float lerp(float a, float b, float t) } -static inline float clamp(float x, float lowerlimit, float upperlimit) { - if (x < lowerlimit) - return lowerlimit; - - if (x > upperlimit) - return upperlimit; - - return x; -} - - -static inline float smootherstep(float edge0, float edge1, float x) { - x = clamp((x - edge0) / (edge1 - edge0), 0.f, 1.f); - +static inline float smootherstep(float x) { return x * x * x * (x * (x * 6.f - 15.f) + 10.f); } @@ -114,11 +101,13 @@ float din(din_t *din, v3f_t *coordinate) float tx, ty, tz; float n0, n1; +#if 0 assert(din); assert(coordinate); assert(coordinate->x >= -1.f && coordinate->x <= 1.f); assert(coordinate->y >= -1.f && coordinate->y <= 1.f); assert(coordinate->z >= -1.f && coordinate->z <= 1.f); +#endif coordinate->x = .5f + (coordinate->x * .5f + .5f) * (float)(din->width - 2); coordinate->y = .5f + (coordinate->y * .5f + .5f) * (float)(din->height - 2); @@ -138,14 +127,14 @@ float din(din_t *din, v3f_t *coordinate) n0 = dotgradient(din, x0, y0, z0, coordinate); n1 = dotgradient(din, x1, y0, z0, coordinate); - tx = smootherstep(0.f, 1.f, tx); + tx = smootherstep(tx); i1 = lerp(n0, n1, tx); n0 = dotgradient(din, x0, y1, z0, coordinate); n1 = dotgradient(din, x1, y1, z0, coordinate); i2 = lerp(n0, n1, tx); - ty = smootherstep(0.f, 1.f, ty); + ty = smootherstep(ty); ii1 = lerp(i1, i2, ty); n0 = dotgradient(din, x0, y0, z1, coordinate); @@ -158,7 +147,7 @@ float din(din_t *din, v3f_t *coordinate) ii2 = lerp(i1, i2, ty); - tz = smootherstep(0.f, 1.f, tz); + tz = smootherstep(tz); return lerp(ii1, ii2, tz) * 1.1547005383792515290182975610039f; } -- cgit v1.2.1