RFR 4641897: Faster string conversion of large integers
Aleksey Shipilev
aleksey.shipilev at oracle.com
Sat Jun 22 10:50:26 UTC 2013
On 06/22/2013 08:06 AM, Dmitry Nadezhin wrote:
> Alexey,
>
> Each possible radix has its cacheLine in the cache.
>
> Cache contents looks like
> BigInteger[][] powerCache = new BigInteger[37] {
> /*0*/ null,
> /*1*/ null,
> /*2*/ new BigInteger[] { 2, 4, 16, 256, 32768, ... },
> /*3*/ new BigInteger[] { 3, 9, 81, ... },
> /*4*/ new BigInteger[] { 4, 16, 256, ... }
> /*5*/ new BigInteger[] { 5, 25, 625, ... },
> /*6*/ new BigInteger[] { 6 },
> /*7*/ new BigInteger[] { 7 },
> . . .
> /*36*/ new BigInteger[] { 36 }
> };
>
> Is there an idiom for a list/array of volatile references ?
AtomicReferenceArray is your friend there. Although I'm not sure why you
need the list of volatile references in this case. Placing volatile to
the root reference resolves the race.
> I am not sure that such naive code works:
> volatile BigInteger[][] powerCache = ..,
Why wouldn't it work?
volatile T[][] cache;
T[] get(int index) {
T[][] lc = cache;
if (index >= lc.length) { // need resizing
lc = generateNew(index << 1);
cache = lc;
}
return lc[index];
}
If you need to populate the 2nd level, then you have to have the final
volatile write to the $cache. The corresponding $cache volatile read
makes the update on 2nd level visible.
T get(int index1, index2) {
T[][] lc = cache;
if (index1 >= lc.length) { // needs resizing
lc = generateNewT2(index1 << 1);
cache = lc;
}
T[] lt = lc[index2];
if (index2 >= lt.length) { // needs resizing
lt = generateNewT1(index2 << 1);
lc[index2] = lt;
cache = lc; // publish
}
return lt[index2];
}
-Aleksey.
More information about the core-libs-dev
mailing list