Commit graph

33 commits

Author SHA1 Message Date
Aaron Patterson
50c2c4bdde Make rb_vm_insns_count a thread local variable
`rb_vm_insns_count` is a global variable used for reporting YJIT
statistics. It is a counter that tallies the number of interpreter
instructions that have been executed, this way we can approximate how
much time we're spending in YJIT compared to the interpreter.

Unfortunately keeping this statistic means that every instruction
executed in the interpreter loop must increment the counter. Normally
this isn't a problem, but in multi-threaded situations (when Ractors are
used), incrementing this counter can become quite costly due to page
caching issues.

Additionally, since there is no locking when incrementing this global,
the count can't really make sense in a multi-threaded environment.

This commit changes `rb_vm_insns_count` to a thread local. That way each
Ractor has it's own copy of the counter and incrementing the counter
becomes quite cheap. Of course this means that in multi-threaded
situations, the value doesn't really make sense (but it didn't make
sense before because of the lack of locking).

The counter is used for YJIT statistics, and since YJIT is basically
disabled when Ractors are in use, I don't think we care about
inaccuracies (for the time being). We can revisit this counter when we
give YJIT multi-threading support, but for the time being this commit
restores multi-threaded performance.

To test this, I used the benchmark in [Bug #20489].

Here is the performance on Ruby 3.2:

```
$ time RUBY_MAX_CPU=12 ./miniruby -v ../test.rb 8 8
ruby 3.2.0 (2022-12-25 revision a528908271) [x86_64-linux]
[0...1, 1...2, 2...3, 3...4, 4...5, 5...6, 6...7, 7...8]
../test.rb:43: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.

________________________________________________________
Executed in    2.53 secs    fish           external
   usr time   19.86 secs  370.00 micros   19.86 secs
   sys time    0.02 secs  320.00 micros    0.02 secs
```

We can see the regression in performance on the master branch:

```
$ time RUBY_MAX_CPU=12 ./miniruby -v ../test.rb 8 8
ruby 3.5.0dev (2025-01-10T16:22:26Z master 4a2702dafb) +PRISM [x86_64-linux]
[0...1, 1...2, 2...3, 3...4, 4...5, 5...6, 6...7, 7...8]
../test.rb:43: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.

________________________________________________________
Executed in   24.87 secs    fish           external
   usr time  195.55 secs    0.00 micros  195.55 secs
   sys time    0.00 secs  716.00 micros    0.00 secs
```

Here are the stats after this commit:

```
$ time RUBY_MAX_CPU=12 ./miniruby -v ../test.rb 8 8
ruby 3.5.0dev (2025-01-10T20:37:06Z tl 3ef0432779) +PRISM [x86_64-linux]
[0...1, 1...2, 2...3, 3...4, 4...5, 5...6, 6...7, 7...8]
../test.rb:43: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.

________________________________________________________
Executed in    2.46 secs    fish           external
   usr time   19.34 secs  381.00 micros   19.34 secs
   sys time    0.01 secs  321.00 micros    0.01 secs
```

[Bug #20489]
2025-01-10 13:39:21 -08:00
Takashi Kokubun
22708be0d7 Revisions for #10198
This fixes some inconsistencies introduced by that PR.
2024-03-12 13:44:48 -07:00
Yusuke Endoh
25d74b9527 Do not include a backtick in error messages and backtraces
[Feature #16495]
2024-02-15 18:42:31 +09:00
Takashi Kokubun
da02d08f27 RJIT: Rewind $! after compilation 2023-12-22 22:18:14 -08:00
Takashi Kokubun
2e0277b133 RJIT: Make --rjit-trace actually work 2023-12-21 21:46:19 -08:00
Takashi Kokubun
64c52cd1c2 RJIT: Add --rjit-trace to allow TracePoint during JIT 2023-12-21 21:05:13 -08:00
Takashi Kokubun
009968a700 RJIT: Avoid incrementing vm_insns_count
during compilation
2023-12-21 17:12:40 -08:00
Takashi Kokubun
c73959cff4 RJIT: Rename pause/resume to disable/enable
like YJIT. They don't work in the same way yet, but it's nice to make
the naming consistent first so that we will not need to rename them
later.
2023-12-21 14:25:41 -08:00
Takashi Kokubun
eb872d1752 RJIT: Share rb_vm_insns_count for vm_insns_count 2023-12-18 23:55:40 -08:00
Koichi Sasada
c4c39082af add flags to rb_postponed_job_preregister
for future extensions.
2023-12-10 15:39:06 +09:00
KJ Tsanaktsidis
f8effa209a Change the semantics of rb_postponed_job_register
Our current implementation of rb_postponed_job_register suffers from
some safety issues that can lead to interpreter crashes (see bug #1991).
Essentially, the issue is that jobs can be called with the wrong
arguments.

We made two attempts to fix this whilst keeping the promised semantics,
but:
  * The first one involved masking/unmasking when flushing jobs, which
    was believed to be too expensive
  * The second one involved a lock-free, multi-producer, single-consumer
    ringbuffer, which was too complex

The critical insight behind this third solution is that essentially the
only user of these APIs are a) internal, or b) profiling gems.

For a), none of the usages actually require variable data; they will
work just fine with the preregistration interface.

For b), generally profiling gems only call a single callback with a
single piece of data (which is actually usually just zero) for the life
of the program. The ringbuffer is complex because it needs to support
multi-word inserts of job & data (which can't be atomic); but nobody
actually even needs that functionality, really.

So, this comit:
  * Introduces a pre-registration API for jobs, with a GVL-requiring
    rb_postponed_job_prereigster, which returns a handle which can be
    used with an async-signal-safe rb_postponed_job_trigger.
  * Deprecates rb_postponed_job_register (and re-implements it on top of
    the preregister function for compatability)
  * Moves all the internal usages of postponed job register
    pre-registration
2023-12-10 15:00:37 +09:00
Takashi Kokubun
417eb83b48 RJIT: Tweak the default call threshold
This number works better on yjit-bench (ruby-lsp).
2023-04-26 18:19:48 -07:00
Takashi Kokubun
19506650ef RJIT: Add --rjit-verify-ctx option 2023-04-04 00:35:29 -07:00
Takashi Kokubun
6002b12611 RJIT: Support entry with different PCs 2023-04-02 15:27:40 -07:00
Takashi Kokubun
d189f8d870 RJIT: Prefix rjit_options with rb_ 2023-03-18 21:28:55 -07:00
Takashi Kokubun
644c998525 RJIT: Support --rjit-stats on release build as well 2023-03-17 22:31:41 -07:00
Takashi Kokubun
9cd5441d28 RJIT: Implement --rjit-trace-exits 2023-03-12 15:15:08 -07:00
Takashi Kokubun
c364e0745d RJIT: Introduce --rjit-exec-mem-size 2023-03-10 13:04:45 -08:00
Takashi Kokubun
3c35c13aaa RJIT: Resurrect --rjit-pause and RJIT.resume 2023-03-09 22:43:53 -08:00
Takashi Kokubun
1a0d3ec4b9 RJIT: Make functions in rjit_c.c static
They don't need to be global.
2023-03-08 23:38:02 -08:00
Takashi Kokubun
4be224eaf5 RJIT: Reorganize rjit.c
Reordering functions for readability, adding stats whenever possible.
2023-03-08 23:31:06 -08:00
Takashi Kokubun
f5909ac6d9 RJIT: Stop allowing leaked globals rjit_* 2023-03-08 23:24:38 -08:00
Takashi Kokubun
a0918a4a80 RJIT: Get rid of verbose logging 2023-03-08 23:12:51 -08:00
Takashi Kokubun
7d7b67a472 RJIT: Clean up the declaration mess 2023-03-08 23:07:30 -08:00
Takashi Kokubun
9ad19069f9 Remove obsoleted functions in rjit.c 2023-03-07 23:59:50 -08:00
Takashi Kokubun
4bf037bebd Update documentation about RJIT 2023-03-07 23:31:39 -08:00
Takashi Kokubun
43de2365a5 Fix a typo 2023-03-07 23:06:01 -08:00
Takashi Kokubun
6d91df08b5
Allow enabling YJIT and RJIT independently (#7474)
We used to require MJIT is supported when YJIT is supported. However,
now that RJIT dropped some platforms that YJIT supports, it no longer
makes sense. We should be able to enable only YJIT, and vice versa.
2023-03-07 22:43:37 -08:00
Takashi Kokubun
0bf4cd8e1c Actually stop supporting those options 2023-03-07 21:21:19 -08:00
Takashi Kokubun
1d39d2d334 Update options available in RJIT 2023-03-07 21:19:04 -08:00
Takashi Kokubun
23ec248e48 s/mjit/rjit/ 2023-03-06 23:44:01 -08:00
Takashi Kokubun
2e875549a9 s/MJIT/RJIT/ 2023-03-06 23:44:01 -08:00
Takashi Kokubun
eaccdc1941 Rename MJIT filenames to RJIT 2023-03-06 23:44:01 -08:00
Renamed from mjit.c (Browse further)