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 4826F17DCBC3 for ; Thu, 27 Nov 2014 20:37:46 +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 2B9FAB5D808 for ; Thu, 27 Nov 2014 20:28:27 +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 8F7A197A827 for ; Thu, 27 Nov 2014 20:28:29 +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 pHvdX85AyhZW for ; Thu, 27 Nov 2014 20:28:29 +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 6CBB497A826 for ; Thu, 27 Nov 2014 20:28:29 +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 C9F9A952408 for ; Thu, 27 Nov 2014 20:28:26 +0900 (JST) Received: from [221.186.184.76] (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 5A6FC120032; Thu, 27 Nov 2014 20:28:22 +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 98101120459 for ; Thu, 27 Nov 2014 20:28:18 +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=PMBJWjssFOelK4tSK1lZAImUz4c=; b=jbqMVu1jbcBn7JYql4 rpDIrrhBEMJvP/mbOqE6RxfDHsNs8eHPZBBjCLu8G+kGbj489GUKRaeCq53vqtSz pBdIuLhQiPzfXsEVBKZKpggTpHdA2waGdB34HicWRMb2EG1gXD++Ew6nXkGdJmQE NaKyZ+kVZi0PvlJp2DBNb1ABE= Received: by filter0047p1mdw1.sendgrid.net with SMTP id filter0047p1mdw1.16181.54770ACE1C 2014-11-27 11:28:15.510881588 +0000 UTC Received: from herokuapp.com (ec2-54-167-133-73.compute-1.amazonaws.com [54.167.133.73]) by ismtpd-029 (SG) with ESMTP id 149f1023a50.180e.b87f for ; Thu, 27 Nov 2014 11:28:15 +0000 (UTC) Date: Thu, 27 Nov 2014 11:28:15 +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: 40916 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/Ymy4QrNMhiuLXJG8OTL2vJD1yS4TFTE6jBsTyouy+mxqIhLVDTCRUmnDDSeViA 5MJ7K5esCvpkHtPuommIcraRo78tEgQUyHrq0GiiM/anhznoZrX/tFLwYg49HeQeYhJe7NSAPi0nH4 kI6gE6ypzQEj8yeaGxUPWol3dW7FZEiHTQJ7 X-ML-Name: ruby-core X-Mail-Count: 66522 Subject: [ruby-core:66522] [ruby-trunk - Bug #10232] 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 updated by Koichi Sasada. Target version changed from current: 2.2.0 to next minor ---------------------------------------- Bug #10232: Trivial change of IMMEDIATE VALUE bits layout https://bugs.ruby-lang.org/issues/10232#change-50137 * Author: Koichi Sasada * Status: Open * Priority: Normal * Assignee: Koichi Sasada * Category: core * 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/