[前][次][番号順一覧][スレッド一覧]

ruby-changes:60616

From: Takashi <ko1@a...>
Date: Wed, 1 Apr 2020 14:11:09 +0900 (JST)
Subject: [ruby-changes:60616] 151f8be40d (master): Make JIT-ed leave insn leaf

https://git.ruby-lang.org/ruby.git/commit/?id=151f8be40d

From 151f8be40d385ada2ebf7feb84210ed7db7ef4df Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Tue, 31 Mar 2020 21:58:01 -0700
Subject: Make JIT-ed leave insn leaf

to eliminate sp / pc moves by cancelling JIT execution on interrupts.

$ benchmark-driver benchmark.yml -v --rbenv 'before --jit;after --jit' --repeat-count=12 --output=all
before --jit: ruby 2.8.0dev (2020-04-01T03:48:56Z master 5a81562dfe) +JIT [x86_64-linux]
after --jit: ruby 2.8.0dev (2020-04-01T04:58:01Z master 39beb26a27) +JIT [x86_64-linux]
Calculating -------------------------------------
                                 before --jit           after --jit
Optcarrot Lan_Master.nes    75.06409603894944     76.06422026555558 fps
                            75.12025067279242     78.48161731616810
                            77.42020273492177     79.78958240950033
                            79.07253675128945     79.88645902325614
                            79.99179109732327     80.33743931749331
                            80.07633091008627     80.53790081529166
                            80.15450942667547     80.99048270668010
                            80.48372803283709     81.70497146081003
                            80.57410149187352     82.79494539467382
                            81.80449157081202     82.85797792223954
                            82.24629397834902     83.00603891515506
                            82.63708148686703     83.23221006969828

$ benchmark-driver -v --rbenv 'before;before --jit;after --jit' benchmark/mjit_leave.yml --repeat-count=4
before: ruby 2.8.0dev (2020-04-01T03:48:56Z master 5a81562dfe) [x86_64-linux]
before --jit: ruby 2.8.0dev (2020-04-01T03:48:56Z master 5a81562dfe) +JIT [x86_64-linux]
after --jit: ruby 2.8.0dev (2020-04-01T04:58:01Z master 39beb26a27) +JIT [x86_64-linux]
Calculating -------------------------------------
                         before  before --jit  after --jit
          mjit_leave   106.656M       82.786M      91.635M i/s -    200.000M times in 1.875183s 2.415881s 2.182569s

Comparison:
                       mjit_leave
              before: 106656239.9 i/s
         after --jit:  91635143.7 i/s - 1.16x  slower
        before --jit:  82785537.2 i/s - 1.29x  slower

diff --git a/benchmark/mjit_leave.yml b/benchmark/mjit_leave.yml
new file mode 100644
index 0000000..292d6ef
--- /dev/null
+++ b/benchmark/mjit_leave.yml
@@ -0,0 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/benchmark/mjit_leave.yml#L1
+prelude: |
+  def leave
+    nil
+  end
+benchmark:
+  mjit_leave: leave
+loop_count: 200000000
diff --git a/tool/ruby_vm/views/mjit_compile.inc.erb b/tool/ruby_vm/views/mjit_compile.inc.erb
index b51e777..500a4fc 100644
--- a/tool/ruby_vm/views/mjit_compile.inc.erb
+++ b/tool/ruby_vm/views/mjit_compile.inc.erb
@@ -70,12 +70,22 @@ switch (insn) { https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/mjit_compile.inc.erb#L70
               fprintf(stderr, "MJIT warning: Unexpected JIT stack_size on leave: %d\n", b->stack_size);
           status->success = false;
       }
-%     # Special leave for an inlined call.
-      if (status->inlined_iseqs == NULL) { // the current ISeq is being inlined
-          fprintf(f, "    return stack[0];\n");
-          b->stack_size += <%= insn.call_attribute('sp_inc') %>;
-          break;
+%     # Skip vm_pop_frame for inlined call
+      if (status->inlined_iseqs != NULL) { // the current ISeq is NOT being inlined
+%         # Cancel on interrupts to make leave insn leaf
+          fprintf(f, "    if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(ec))) {\n");
+          if (status->local_stack_p) {
+              fprintf(f, "        reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size);
+          }
+          fprintf(f, "        reg_cfp->pc = original_body_iseq + %d;\n", pos);
+          fprintf(f, "        goto cancel;\n");
+          fprintf(f, "    }\n");
+          fprintf(f, "    ec->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(reg_cfp);\n"); // vm_pop_frame
       }
+      fprintf(f, "    return stack[0];\n");
+      b->stack_size += <%= insn.call_attribute('sp_inc') %>;
+      b->finish_p = TRUE;
+      break;
 %   end
 %
 %   # Main insn implementation generated by insns.def
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]