[#79440] [Ruby trunk Bug#13188] Reinitialize Ruby VM. — shyouhei@...
Issue #13188 has been updated by Shyouhei Urabe.
6 messages
2017/02/06
[#79441] Re: [Ruby trunk Bug#13188] Reinitialize Ruby VM.
— SASADA Koichi <ko1@...>
2017/02/06
On 2017/02/06 10:10, shyouhei@ruby-lang.org wrote:
[#79532] Immutable Strings vs Symbols — Daniel Ferreira <subtileos@...>
Hi,
15 messages
2017/02/15
[#79541] Re: Immutable Strings vs Symbols
— Rodrigo Rosenfeld Rosas <rr.rosas@...>
2017/02/15
Em 15-02-2017 05:05, Daniel Ferreira escreveu:
[#79543] Re: Immutable Strings vs Symbols
— Daniel Ferreira <subtileos@...>
2017/02/16
Hi Rodrigo,
[#79560] Re: Immutable Strings vs Symbols
— Rodrigo Rosenfeld Rosas <rr.rosas@...>
2017/02/16
Em 15-02-2017 22:39, Daniel Ferreira escreveu:
[ruby-core:79444] [Ruby trunk Bug#10232][Rejected] Trivial change of IMMEDIATE VALUE bits layout
From:
ko1@...
Date:
2017-02-06 02:55:52 UTC
List:
ruby-core #79444
Issue #10232 has been updated by Koichi Sasada.
Status changed from Open to Rejected
Reject it and revisit sometime.
----------------------------------------
Bug #10232: Trivial change of IMMEDIATE VALUE bits layout
https://bugs.ruby-lang.org/issues/10232#change-62875
* Author: Koichi Sasada
* Status: Rejected
* Priority: Normal
* Assignee: Koichi Sasada
* Target version: next minor
* ruby -v: 2.2
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN
----------------------------------------
The following patch improves performance a bit.
```
!USE_FLONUM
-------------------------
...xxxx xxx1 Fixnum
...0000 1110 Symbol
...0000 0000 Qfalse
...0000 0010 Qtrue
...0000 0100 Qnil
...0000 0110 Qundef
USE_FLONUM
-------------------------
...xxxx xxx1 Fixnum
...xxxx xx10 Flonum
...0000 1100 Symbol
...0000 0000 Qfalse 0x00 = 0
...0000 1000 Qnil 0x08 = 8
...0001 0100 Qtrue 0x14 = 20
...0011 0100 Qundef 0x34 = 52
#=>
!USE_FLONUM
-------------------------
xxxx xxxx xxx1 Fixnum 0x01
xxxx 0011 0010 Symbol 0x32 = 50
0000 0000 0000 Qfalse 0x00
0000 0000 0010 Qnil 0x02
0000 0001 0010 Qtrue 0x12 = 18
0000 0010 0010 Qundef 0x22 = 32
USE_FLONUM
-------------------------
xxxx xxxx xxx1 Fixnum 0x01
xxxx xxxx xx10 Flonum 0x02
xxxx 0011 0100 Symbol 0x34 = 52
0000 0000 0000 Qfalse 0x00 = 0
0000 0000 0100 Qnil 0x04 = 4
0000 0001 0100 Qtrue 0x14 = 20
0000 0010 0100 Qundef 0x24 = 36
```
```patch
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h (revision 47531)
+++ include/ruby/ruby.h (working copy)
@@ -395,6 +395,27 @@ USE_FLONUM
...0000 1000 Qnil 0x08 = 8
...0001 0100 Qtrue 0x14 = 20
...0011 0100 Qundef 0x34 = 52
+
+#=>
+
+!USE_FLONUM
+-------------------------
+xxxx xxxx xxx1 Fixnum 0x01
+xxxx 0011 0010 Symbol 0x32 = 50
+0000 0000 0000 Qfalse 0x00
+0000 0000 0010 Qnil 0x02
+0000 0001 0010 Qtrue 0x12 = 18
+0000 0010 0010 Qundef 0x22 = 32
+
+USE_FLONUM
+-------------------------
+xxxx xxxx xxx1 Fixnum 0x01
+xxxx xxxx xx10 Flonum 0x02
+xxxx 0011 0100 Symbol 0x34 = 52
+0000 0000 0000 Qfalse 0x00 = 0
+0000 0000 0100 Qnil 0x04 = 4
+0000 0001 0100 Qtrue 0x14 = 20
+0000 0010 0100 Qundef 0x24 = 36
*/
/* special constants - i.e. non-zero and non-fixnum constants */
@@ -402,26 +423,26 @@ enum ruby_special_consts {
#if USE_FLONUM
RUBY_Qfalse = 0x00,
RUBY_Qtrue = 0x14,
- RUBY_Qnil = 0x08,
- RUBY_Qundef = 0x34,
+ RUBY_Qnil = 0x04,
+ RUBY_Qundef = 0x24,
RUBY_IMMEDIATE_MASK = 0x07,
RUBY_FIXNUM_FLAG = 0x01,
RUBY_FLONUM_MASK = 0x03,
RUBY_FLONUM_FLAG = 0x02,
- RUBY_SYMBOL_FLAG = 0x0c,
+ RUBY_SYMBOL_FLAG = 0x34,
RUBY_SPECIAL_SHIFT = 8
#else
- RUBY_Qfalse = 0,
- RUBY_Qtrue = 2,
- RUBY_Qnil = 4,
- RUBY_Qundef = 6,
+ RUBY_Qfalse = 0x00,
+ RUBY_Qtrue = 0x12,
+ RUBY_Qnil = 0x02,
+ RUBY_Qundef = 0x22,
RUBY_IMMEDIATE_MASK = 0x03,
RUBY_FIXNUM_FLAG = 0x01,
RUBY_FLONUM_MASK = 0x00, /* any values ANDed with FLONUM_MASK cannot be FLONUM_FLAG */
RUBY_FLONUM_FLAG = 0x02,
- RUBY_SYMBOL_FLAG = 0x0e,
+ RUBY_SYMBOL_FLAG = 0x32,
RUBY_SPECIAL_SHIFT = 8
#endif
};
@@ -1106,7 +1127,7 @@ struct RStruct {
#define FL_USER18 (((VALUE)1)<<(FL_USHIFT+18))
#define FL_USER19 (((VALUE)1)<<(FL_USHIFT+19))
-#define SPECIAL_CONST_P(x) (IMMEDIATE_P(x) || !RTEST(x))
+#define SPECIAL_CONST_P(x) (IMMEDIATE_P(x) || !(x))
#define FL_ABLE(x) (!SPECIAL_CONST_P(x) && BUILTIN_TYPE(x) != T_NODE)
#define FL_TEST_RAW(x,f) (RBASIC(x)->flags&(f))
@@ -1583,11 +1604,9 @@ rb_class_of(VALUE obj)
if (FLONUM_P(obj)) return rb_cFloat;
if (obj == Qtrue) return rb_cTrueClass;
if (STATIC_SYM_P(obj)) return rb_cSymbol;
- }
- else if (!RTEST(obj)) {
if (obj == Qnil) return rb_cNilClass;
- if (obj == Qfalse) return rb_cFalseClass;
}
+ else if (obj == Qfalse) return rb_cFalseClass;
return RBASIC(obj)->klass;
}
@@ -1600,11 +1619,9 @@ rb_type(VALUE obj)
if (obj == Qtrue) return T_TRUE;
if (STATIC_SYM_P(obj)) return T_SYMBOL;
if (obj == Qundef) return T_UNDEF;
- }
- else if (!RTEST(obj)) {
if (obj == Qnil) return T_NIL;
- if (obj == Qfalse) return T_FALSE;
}
+ else if (obj == Qfalse) return T_FALSE;
return BUILTIN_TYPE(obj);
}
```
The change is:
(1) IMMEDIATE_P(Qnil) => TRUE
(2) SPECIAL_CONST_P(x) becomes a bit simple -> (IMMEDIATE_P(x) || !(x))
(1) can be incompatibility issue so that I don't propose this fix strongly.
Interpreter core doesn't depends on this spec, but C-exts can be affected.
Benchmark result is: http://www.atdot.net/sp/raw/stirbn (gitruby is modified version)
Strange thing is: vm1_const
```
vm1_const
Const = 1
i = 0
while i<30_000_000 # while loop 1
i += 1
j = Const
k = Const
end
trunk 1.057002067565918
trunk 1.07387113571167
trunk 1.3638195991516113
trunk 1.076874017715454
trunk 1.0717082023620605
gitruby 0.7370171546936035
gitruby 0.7366814613342285
gitruby 0.7377498149871826
gitruby 0.7381434440612793
gitruby 0.7375714778900146
```
vm1_const only repeats `getinlinecache' instruction. I'm not sure why it has impact.
Change this program to repeat accessing constant more:
```
Const = 1
i = 0
while i<30_000_000 # while loop 1
i += 1
j = Const
k = Const
k = Const
k = Const
k = Const
k = Const
k = Const
k = Const
k = Const
k = Const
k = Const
k = Const
k = Const
end
trunk 2.2485034465789795
trunk 2.2310359477996826
trunk 2.2247872352600098
trunk 2.2434682846069336
trunk 2.225156307220459
gitruby 2.2048048973083496
gitruby 2.2114696502685547
gitruby 2.2110848426818848
gitruby 2.208353042602539
gitruby 2.2142462730407715
```
It can be accidentally.
Other variations:
```
vm1_const
Const = 1
i = 0
while i<30_000_000 # while loop 1
i += 1
k = Const
end
trunk 0.6202449798583984
trunk 0.8297767639160156
trunk 0.6203830242156982
trunk 0.6206128597259521
trunk 0.6202561855316162
gitruby 0.6209316253662109
gitruby 0.6197938919067383
gitruby 0.6191442012786865
gitruby 0.6194281578063965
gitruby 0.6211118698120117
```
```
vm1_const
Const = 1
i = 0
while i<30_000_000 # while loop 1
i += 1
j = Const
k = Const
l = Const
end
trunk 1.195659875869751
trunk 1.1864018440246582
trunk 1.1857333183288574
trunk 1.17852783203125
trunk 1.177058458328247
gitruby 1.1888437271118164
gitruby 1.1901893615722656
gitruby 1.1873669624328613
gitruby 1.187666893005371
gitruby 1.182875156402588
```
It seems that such strange behaviour only on two Const accessing.
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>