From: ko1@atdot.net
To: ruby-core@ruby-lang.org
Subject: [ruby-core:64987] [ruby-trunk - Bug #10232] Trivial change of IMMEDIATE VALUE bits layout
Date: Fri, 12 Sep 2014 03:31:56 +0000 [thread overview]
Message-ID: <redmine.journal-48862.20140912033156.87285fdf6aeb135c@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-10232.20140912012732@ruby-lang.org
Issue #10232 has been updated by Koichi Sasada.
Eric Wong wrote:
> > Strange thing is: vm1_const
>
> I suspect this is CPU-specific behaviors. I cannot see the difference
> on my AMD FX-8320 (on vm1_const, haven't tested others)
I agree.
----------------------------------------
Bug #10232: Trivial change of IMMEDIATE VALUE bits layout
https://bugs.ruby-lang.org/issues/10232#change-48862
* Author: Koichi Sasada
* Status: Open
* Priority: Normal
* Assignee: Koichi Sasada
* Category: core
* Target version: current: 2.2.0
* 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/
next prev parent reply other threads:[~2014-09-12 3:52 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <redmine.issue-10232.20140912012732@ruby-lang.org>
2014-09-12 1:27 ` [ruby-core:64979] [ruby-trunk - Bug #10232] [Open] Trivial change of IMMEDIATE VALUE bits layout ko1
2014-09-12 2:59 ` [ruby-core:64985] " Eric Wong
2014-09-12 3:10 ` [ruby-core:64986] [ruby-trunk - Bug #10232] " normalperson
2014-09-12 3:31 ` ko1 [this message]
2014-11-27 11:28 ` [ruby-core:66522] " ko1
2017-02-06 2:55 ` [ruby-core:79444] [Ruby trunk Bug#10232][Rejected] " ko1
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.ruby-lang.org/en/community/mailing-lists/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=redmine.journal-48862.20140912033156.87285fdf6aeb135c@ruby-lang.org \
--to=ruby-core@ruby-lang.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).