mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-19 14:55:17 +00:00
8017540: Improve multi-threaded contention behavior of radix conversion cache
Replace array of ArrayList of BigIntegers with a volatile two-dimensional BigInteger array eliminate the synchronization of getRadixConversionCache() Co-authored-by: Dmitry Nadezhin <dmitry.nadezhin@oracle.com> Co-authored-by: Aleksey Shipilev <aleksey.shipilev@oracle.com> Reviewed-by: plevart, shade, bpb, alanb
This commit is contained in:
parent
53ecefacac
commit
329abc4028
@ -1042,7 +1042,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
* recalculate powers of radix^(2^n) more than once. This speeds
|
||||
* Schoenhage recursive base conversion significantly.
|
||||
*/
|
||||
private static ArrayList<BigInteger>[] powerCache;
|
||||
private static volatile BigInteger[][] powerCache;
|
||||
|
||||
/** The cache of logarithms of radices for base conversion. */
|
||||
private static final double[] logCache;
|
||||
@ -1063,14 +1063,12 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
* with just the very first value. Additional values will be created
|
||||
* on demand.
|
||||
*/
|
||||
powerCache = (ArrayList<BigInteger>[])
|
||||
new ArrayList[Character.MAX_RADIX+1];
|
||||
powerCache = new BigInteger[Character.MAX_RADIX+1][];
|
||||
logCache = new double[Character.MAX_RADIX+1];
|
||||
|
||||
for (int i=Character.MIN_RADIX; i<=Character.MAX_RADIX; i++)
|
||||
{
|
||||
powerCache[i] = new ArrayList<BigInteger>(1);
|
||||
powerCache[i].add(BigInteger.valueOf(i));
|
||||
powerCache[i] = new BigInteger[] { BigInteger.valueOf(i) };
|
||||
logCache[i] = Math.log(i);
|
||||
}
|
||||
}
|
||||
@ -3454,22 +3452,25 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
* This could be changed to a more complicated caching method using
|
||||
* <code>Future</code>.
|
||||
*/
|
||||
private static synchronized BigInteger getRadixConversionCache(int radix,
|
||||
int exponent) {
|
||||
BigInteger retVal = null;
|
||||
ArrayList<BigInteger> cacheLine = powerCache[radix];
|
||||
int oldSize = cacheLine.size();
|
||||
if (exponent >= oldSize) {
|
||||
cacheLine.ensureCapacity(exponent+1);
|
||||
for (int i=oldSize; i<=exponent; i++) {
|
||||
retVal = cacheLine.get(i-1).square();
|
||||
cacheLine.add(i, retVal);
|
||||
}
|
||||
private static BigInteger getRadixConversionCache(int radix, int exponent) {
|
||||
BigInteger[] cacheLine = powerCache[radix]; // volatile read
|
||||
if (exponent < cacheLine.length) {
|
||||
return cacheLine[exponent];
|
||||
}
|
||||
else
|
||||
retVal = cacheLine.get(exponent);
|
||||
|
||||
return retVal;
|
||||
int oldLength = cacheLine.length;
|
||||
cacheLine = Arrays.copyOf(cacheLine, exponent + 1);
|
||||
for (int i = oldLength; i <= exponent; i++) {
|
||||
cacheLine[i] = cacheLine[i - 1].pow(2);
|
||||
}
|
||||
|
||||
BigInteger[][] pc = powerCache; // volatile read again
|
||||
if (exponent >= pc[radix].length) {
|
||||
pc = pc.clone();
|
||||
pc[radix] = cacheLine;
|
||||
powerCache = pc; // volatile write, publish
|
||||
}
|
||||
return cacheLine[exponent];
|
||||
}
|
||||
|
||||
/* zero[i] is a string of i consecutive zeros. */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user