[前][次][番号順一覧][スレッド一覧]

ruby-changes:42864

From: nobu <ko1@a...>
Date: Sat, 7 May 2016 15:25:38 +0900 (JST)
Subject: [ruby-changes:42864] nobu:r54938 (trunk): random.c: optimize int_pair_to_real_inclusive

nobu	2016-05-07 16:22:14 +0900 (Sat, 07 May 2016)

  New Revision: 54938

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54938

  Log:
    random.c: optimize int_pair_to_real_inclusive
    
    * random.c (int_pair_to_real_inclusive): optimize to multiply
      without Bignum.

  Modified files:
    trunk/ChangeLog
    trunk/random.c
Index: random.c
===================================================================
--- random.c	(revision 54937)
+++ random.c	(revision 54938)
@@ -279,41 +279,23 @@ rb_genrand_real(void) https://github.com/ruby/ruby/blob/trunk/random.c#L279
 static double
 int_pair_to_real_inclusive(uint32_t a, uint32_t b)
 {
-    VALUE x;
-    VALUE m;
-    uint32_t xary[2], mary[2];
     double r;
-
-    /* (a << 32) | b */
-    xary[0] = a;
-    xary[1] = b;
-    x = rb_integer_unpack(xary, 2, sizeof(uint32_t), 0,
-        INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER|
-        INTEGER_PACK_FORCE_BIGNUM);
-
-    /* (1 << 53) | 1 */
-    mary[0] = 0x00200000;
-    mary[1] = 0x00000001;
-    m = rb_integer_unpack(mary, 2, sizeof(uint32_t), 0,
-        INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER|
-        INTEGER_PACK_FORCE_BIGNUM);
-
-    x = rb_big_mul(x, m);
-    if (FIXNUM_P(x)) {
-#if CHAR_BIT * SIZEOF_LONG > 64
-	r = (double)(FIX2ULONG(x) >> 64);
+    enum {dig = 53};
+    enum {dig_u = dig-32, dig_r64 = 64-dig, bmask = ~(~0u<<(dig_r64))};
+#if defined HAVE_UINT128_T
+    const uint128_t m = ((uint128_t)1 << dig) | 1;
+    uint128_t x = ((uint128_t)a << 32) | b;
+    r = (double)(uint64_t)((x * m) >> 64);
+#elif defined HAVE_UINT64_T
+    uint64_t x = ((uint64_t)a << dig_u) +
+	(((uint64_t)b + (a >> dig_u)) >> dig_r64);
+    r = (double)x;
 #else
-	return 0.0;
+    /* shift then add to get rid of overflow */
+    b = (b >> dig_r64) + (((a >> dig_u) + (b & bmask)) >> dig_r64);
+    r = (double)a * (1 << dig_u) + b;
 #endif
-    }
-    else {
-        uint32_t uary[4];
-        rb_integer_pack(x, uary, numberof(uary), sizeof(uint32_t), 0,
-                INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
-        /* r = x >> 64 */
-        r = (double)uary[0] * (0x10000 * (double)0x10000) + (double)uary[1];
-    }
-    return ldexp(r, -53);
+    return ldexp(r, -dig);
 }
 
 VALUE rb_cRandom;
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 54937)
+++ ChangeLog	(revision 54938)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat May  7 16:22:13 2016  Nobuyoshi Nakada  <nobu@r...>
+
+	* random.c (int_pair_to_real_inclusive): optimize to multiply
+	  without Bignum.
+
 Sat May  7 07:58:02 2016  Nobuyoshi Nakada  <nobu@r...>
 
 	* process.c (rb_exec_getargs): honor the expected argument types

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]