This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug java/23283] Sun's JIT faster than gcc for Random.nextDouble
- From: "bonzini at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 23 Aug 2005 14:48:52 -0000
- Subject: [Bug java/23283] Sun's JIT faster than gcc for Random.nextDouble
- References: <20050808100453.23283.netzberg@gmail.com>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From bonzini at gcc dot gnu dot org 2005-08-23 14:48 -------
Yes, I think that most invocations of next should be inlined, and wrapped in a
single synchronized block.
Apart from that, I am pretty sure that here
seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (int) (seed >>> (48 - bits));
it makes no difference if you do the AND or not.
So nextDouble could be implemented as:
long first;
long second;
synchronized (this) {
seed = (seed * 0x5DEECE66DL + 0xBL);
first = (seed & 0x0000FFFFFFC00000L) << 5;
seed = (seed * 0x5DEECE66DL + 0xBL);
second = (seed >> 21) & 0x7FFFFFF;
}
return (first | second) / (double) (1L << 53);
Similarly, for nextFloat
float f;
int bits;
synchronized (this) {
seed = (seed * 0x5DEECE66DL + 0xBL);
bits = (int) (seed >> 24);
}
return bits / 16777216.0f;
nextInt
int bits;
synchronized (this) {
seed = (seed * 0x5DEECE66DL + 0xBL);
bits = (int) (seed >> 16);
}
nextLong
long first, second;
synchronized (this) {
seed = (seed * 0x5DEECE66DL + 0xBL);
first = (seed << 16) & 0xFFFFFFFF00000000L;
seed = (seed * 0x5DEECE66DL + 0xBL);
second = (seed >> 16) & 0xFFFFFFFFL;
}
return first | second;
nextInt (n)
int bits;
synchronized (seed)
{
seed = (seed * 0x5DEECE66DL + 0xBL);
bits = (int) (seed >> 17);
}
if ((n & -n) == n) // i.e., n is a power of 2
return (int)((n * (long) bits) >> 31);
int bits, val;
val = bits % n;
if (bits - val + n - 1 < 0)
synchronized (seed)
{
do
{
seed = (seed * 0x5DEECE66DL + 0xBL);
bits = (int) (seed >> 17);
}
while (bits - val + n - 1 < 0);
}
return val;
nextBoolean
boolean bit;
synchronized (this) {
seed = (seed * 0x5DEECE66DL + 0xBL);
bit = (seed & 0x800000000000) != 0;
}
return bit;
And I left out nextBytes, I know.
Also these are untested, which is why I'm not preparing a full patch.
Paolo
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23283