base: Optimize and otherwise fix a couple of functions in intmath.hh.
authorGabe Black <gabeblack@google.com>
Wed, 4 Mar 2020 01:41:44 +0000 (17:41 -0800)
committerGabe Black <gabeblack@google.com>
Thu, 5 Mar 2020 23:42:44 +0000 (23:42 +0000)
commitf4cf31f5e1a952e8fb53e10160f167f29324c3b3
tree009d81585f19ecbb3cc92dfc0b5ad857e6a22781
parent8dc904cb9308ed62f8410f9c1ef04ec6a76e7671
base: Optimize and otherwise fix a couple of functions in intmath.hh.

As described in the Jira issue, this replaces the implementation of
isPowerOf2() and power(). It also revamps floorLog2 so that there only
needs to be one implementation and no assumptions about how big certain
types are.

The way power() used to work was to raise a number n to an exponent e
by multiplying n times itself e times. As a warning in this function
explains, this can be quite slow for large e. A much more efficient
way to raise a number to an exponent is to square n over and over, and
to multiply in the current square if that bit of e is set.

n ^ 15 = (n^1) * (n^2) * (n^4) * (n^8)
n^8 = (n^4)^2
n^4 = (n^2)^2
n^2 = n^2
n^1 = n

So that takes 6 multiplications, n^2, (n^2)^2, (n^4)^2, and then each
multipy to compute the final result, instead of 14.

The difference is more pronounced for larger exponents, although you'd
quickly start to overflow a uint64_t.

Jira Issue: https://gem5.atlassian.net/browse/GEM5-140

Change-Id: I0ae05aeba1b5882d2a616613b1679e6206b4cbfe
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/26164
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/base/intmath.hh
src/base/intmath.test.cc