Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

YJIT: Support ifunc on invokeblock #7233

Merged
merged 1 commit into from Feb 3, 2023
Merged

Conversation

k0kubun
Copy link
Member

@k0kubun k0kubun commented Feb 2, 2023

This is the ifunc support that was skipped in #6640.

It's not used that much now, but converting Array#each to Ruby #6687 makes it used significantly more often. I'd like to introduce this support first for fair comparison.

#6687 reduces ratio_in_yjit from 91.7% to 88.8% on railsbench with run_once.sh, but merging this PR to that branch improves it from 88.8% to 89.8%. We also need to support iseq_arg0_splat to fully recover it, but it should be done in another PR.

This does help reducing invokeblock exits on a few benchmarks on master as well:

hexapdf

Before

invokeblock exit reasons:
               ifunc      17053 (46.9%)
                proc      16764 (46.1%)
    iseq_tag_changed       2511 ( 6.9%)

After

invokeblock exit reasons:
      proc      16764 (99.5%)
    symbol         83 ( 0.5%)

railsbench

Before

invokeblock exit reasons:
               ifunc       5690 (59.5%)
     iseq_arg0_splat       2000 (20.9%)
                proc       1112 (11.6%)
    iseq_tag_changed        727 ( 7.6%)
              symbol         32 ( 0.3%)

After

invokeblock exit reasons:
    iseq_arg0_splat       2000 (51.7%)
               proc       1112 (28.7%)
             symbol        759 (19.6%)

SFR

This might help SFR more than those benchmarks. On Jan 19th, we had:

invokeblock exit reasons:
                 ifunc    1811594 (70.8%)
                  proc     401048 (15.7%)
      iseq_tag_changed     288100 (11.3%)
    iseq_block_changed      56844 ( 2.2%)

Top-20 most frequent exit ops (100.0% of exits):
                        ...
               invokeblock:    3918833 (2.2%)

@k0kubun k0kubun force-pushed the yjit-ifunc branch 2 times, most recently from 1e35fc0 to 0343dfe Compare February 2, 2023 22:05
@k0kubun k0kubun marked this pull request as ready for review February 2, 2023 23:31
@matzbot matzbot requested a review from a team February 2, 2023 23:31
extern "C" {
fn rb_vm_yield_with_cfunc(ec: EcPtr, captured: *const rb_captured_block, argc: c_int, argv: *const VALUE) -> VALUE;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish we could directly call the ifunc instead of calling a C function which calls the ifunc so we could shave off a bit more overhead, but I understand that this is much simpler for a first PR and getting it to work is the most important.

Copy link
Contributor

@maximecb maximecb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for taking care of these side-exits. I'm looking forward to seeing if we can beat the C version once we no longer side-exit in the Ruby Array#each!

@maximecb maximecb merged commit 08c529b into ruby:master Feb 3, 2023
93 checks passed
@maximecb maximecb deleted the yjit-ifunc branch February 3, 2023 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants