RFR: 8234331: Add robust and optimized utility for rounding up to next power of two+
Claes Redestad
claes.redestad at oracle.com
Thu Dec 5 14:59:16 UTC 2019
On 2019-12-05 11:26, Thomas Stüfe wrote:
> Hi Claes,
>
> this looks nice, thank you for your work. Only minor stuff remains,
> mostly matters of taste. Feel free to ignore them. The patch is already
> fine as it is for me.
>
> With your latest patch, AIX still works.
Great!
>
> ---
>
> http://cr.openjdk.java.net/~redestad/8234331/open.04/src/hotspot/share/utilities/count_leading_zeros.hpp.udiff.html
>
> Taste matter: I find the return type for count_leading_zeros as uint32_t
> oddly specific. Instinctively I would have choosen int or unsigned. The
> gcc buildins all return int.
No particular reason.
>
> ---
>
> Question, why do we treat signed numbers of 8 and 16 bits different wrt
> to values < 0?
>
> if you leave behavior as it is, could you please adjust the comment:
>
> // Return the number of leading zeros in x, e.g. the zero-based index
> // of the most significant set bit in x. Undefined for 0.
> + // For signed numbers whose size is < 32bit, function will
> + // return 0 for values < 0.
Such a comment is a bit redundant since count_leading_zeros will return
0 for any negative input. Maybe we should spell that out more clearly,
though.
The special cases avoided issues with sign extension when upcasting,
e.g, casting int8_t -1 to unsigned returns 0xFFFFFFFF, so
__builtin_clz((int8_t)-1) returns 0, which then messes up the manual
adjustment. But this can be further simplified by masking, avoiding
an extra branch:
template <typename T> struct CountLeadingZerosImpl<T, 1> {
static uint32_t doit(T v) {
return __builtin_clz((uint32_t)v & 0xFF) - 24u;
}
};
template <typename T> struct CountLeadingZerosImpl<T, 2> {
static uint32_t doit(T v) {
return __builtin_clz((uint32_t)v & 0xFFFF) - 16u;
}
};
>
> ----
>
> Taste matter: Windows, 64bit version for x86: You could call your own
> count_leading_zeros<uint32_t>, instead of calling _BitScanReverse.
Sure.
>
> ----
>
> http://cr.openjdk.java.net/~redestad/8234331/open.04/test/hotspot/gtest/utilities/test_powerOfTwo.cpp.html
>
> In the test for next_up, can we have, for completeness sake, a test
> which tests that with any valid input pow2 the result is the next pow2?
>
> --- a/test/hotspot/gtest/utilities/test_powerOfTwo.cpp Thu Dec 05
> 02:28:58 2019 +0100
> +++ b/test/hotspot/gtest/utilities/test_powerOfTwo.cpp Thu Dec 05
> 11:08:47 2019 +0100
> @@ -139,6 +139,11 @@
> EXPECT_EQ(pow2, next_power_of_2(pow2 - 1))
> << "value = " << pow2 - 1;
> }
> + // next(pow2) should return pow2 * 2
> + for (T pow2 = T(1); pow2 < t_max_pow2 / 2; pow2 = pow2 * 2) {
> + EXPECT_EQ(pow2 * 2, next_power_of_2(pow2))
> + << "value = " << pow2;
> + }
Fixed.
I also ran into an issue with use of std::numeric_limit<T>::max()
causing obscure issues on some platforms at some call sites (*cough*
Solaris), so I replaced those usages with a portable (but not very
efficient) version of that in place for the few assert/test uses:
http://cr.openjdk.java.net/~redestad/8234331/open.05
Testing: tier1-3, some ongoing
/Claes
More information about the hotspot-runtime-dev
mailing list