From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: poffice@blade.nagaokaut.ac.jp Delivered-To: poffice@blade.nagaokaut.ac.jp Received: from kankan.nagaokaut.ac.jp (kankan.nagaokaut.ac.jp [133.44.2.24]) by blade.nagaokaut.ac.jp (Postfix) with ESMTP id A1B8917D93B1 for ; Fri, 12 Sep 2014 10:47:56 +0900 (JST) Received: from funfun.nagaokaut.ac.jp (funfun.nagaokaut.ac.jp [133.44.2.201]) by kankan.nagaokaut.ac.jp (Postfix) with ESMTP id CA964B5D8F8 for ; Fri, 12 Sep 2014 10:27:46 +0900 (JST) Received: from funfun.nagaokaut.ac.jp (localhost.nagaokaut.ac.jp [127.0.0.1]) by funfun.nagaokaut.ac.jp (Postfix) with ESMTP id F1A7497A836 for ; Fri, 12 Sep 2014 10:27:47 +0900 (JST) X-Virus-Scanned: amavisd-new at nagaokaut.ac.jp Authentication-Results: funfun.nagaokaut.ac.jp (amavisd-new); dkim=fail (1024-bit key) reason="fail (message has been altered)" header.d=sendgrid.me Received: from funfun.nagaokaut.ac.jp ([127.0.0.1]) by funfun.nagaokaut.ac.jp (funfun.nagaokaut.ac.jp [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id G6BSGNHeuOSe for ; Fri, 12 Sep 2014 10:27:47 +0900 (JST) Received: from voscc.nagaokaut.ac.jp (voscc.nagaokaut.ac.jp [133.44.1.100]) by funfun.nagaokaut.ac.jp (Postfix) with ESMTP id B99E197A834 for ; Fri, 12 Sep 2014 10:27:47 +0900 (JST) Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by voscc.nagaokaut.ac.jp (Postfix) with ESMTP id 1D5A695243E for ; Fri, 12 Sep 2014 10:27:45 +0900 (JST) Received: from [221.186.184.76] (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 914EE12046A; Fri, 12 Sep 2014 10:27:38 +0900 (JST) X-Original-To: ruby-core@ruby-lang.org Delivered-To: ruby-core@ruby-lang.org Received: from o2.heroku.sendgrid.net (o2.heroku.sendgrid.net [67.228.50.55]) by neon.ruby-lang.org (Postfix) with ESMTPS id C7EE612040C for ; Fri, 12 Sep 2014 10:27:35 +0900 (JST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sendgrid.me; h=from:to:references:subject:mime-version:content-type:content-transfer-encoding:list-id; s=smtpapi; bh=qfR5WIt60XhRxjYjzwy1FbMga40=; b=di8G8VKAjrHTRVeYMk X+OxZXcZaWuTaRyyN0kW1OgyTG1/x/7WSvnGJOC38jP50kT9jvXoGq4j4KlCbPNE dU25ngjmGRGGFYyYvUOfal5Gmv5CvTdN+H9Ub4MvpS+LQj3xn3lGSvR/OA4jVjZ6 0S1bi5UHv9QsJIwWbN5jUgWig= Received: by mf161.sendgrid.net with SMTP id mf161.3565.54124C0143 2014-09-12 01:27:33.299007198 +0000 UTC Received: from herokuapp.com (ec2-54-82-204-46.compute-1.amazonaws.com [54.82.204.46]) by ismtpd-017.iad1.sendgrid.net (SG) with ESMTP id 1486778f420.4e79.40e1f7 for ; Fri, 12 Sep 2014 01:27:33 +0000 (GMT) Date: Fri, 12 Sep 2014 01:27:32 +0000 From: ko1@atdot.net To: ruby-core@ruby-lang.org Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Redmine-MailingListIntegration-Message-Ids: 39205 X-Redmine-Project: ruby-trunk X-Redmine-Issue-Id: 10232 X-Redmine-Issue-Author: ko1 X-Redmine-Issue-Assignee: ko1 X-Redmine-Sender: ko1 X-Mailer: Redmine X-Redmine-Host: bugs.ruby-lang.org X-Redmine-Site: Ruby Issue Tracking System X-Auto-Response-Suppress: OOF Auto-Submitted: auto-generated X-SG-EID: ync6xU2WACa70kv/Ymy4QrNMhiuLXJG8OTL2vJD1yS7d/5nK0EU7lATGJLSCYOHcCM4FwCLdrAazUEp3tXkxfYcrhRNg/Zmq4ni0qKJ+L9UHXL7EH5g6O8TCYDz8BV6DiaCVqT37k1IYcGVrDle00oxvdlC5HrSrvSbI+8G0uXU= X-SendGrid-Contentd-ID: {"test_id":"1410485253"} X-ML-Name: ruby-core X-Mail-Count: 64979 Subject: [ruby-core:64979] [ruby-trunk - Bug #10232] [Open] Trivial change of IMMEDIATE VALUE bits layout X-BeenThere: ruby-core@ruby-lang.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: Ruby developers List-Id: Ruby developers List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: ruby-core-bounces@ruby-lang.org Sender: "ruby-core" Issue #10232 has been reported by Koichi Sasada. ---------------------------------------- Bug #10232: Trivial change of IMMEDIATE VALUE bits layout https://bugs.ruby-lang.org/issues/10232 * 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/