This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug java/23283] Sun's JIT faster than gcc for Random.nextDouble


------- 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]