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/