mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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 master5a81562dfe
) +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 master5a81562dfe
) [x86_64-linux] before --jit: ruby 2.8.0dev (2020-04-01T03:48:56Z master5a81562dfe
) +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
This commit is contained in:
parent
5a81562dfe
commit
151f8be40d
2 changed files with 22 additions and 5 deletions
7
benchmark/mjit_leave.yml
Normal file
7
benchmark/mjit_leave.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
prelude: |
|
||||
def leave
|
||||
nil
|
||||
end
|
||||
benchmark:
|
||||
mjit_leave: leave
|
||||
loop_count: 200000000
|
|
@ -70,12 +70,22 @@ switch (insn) {
|
|||
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
|
||||
|
|
Loading…
Reference in a new issue