-
Notifications
You must be signed in to change notification settings - Fork 5.4k
shape.c: Implement a lock-free version of get_next_shape_internal #13441
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
Conversation
314d196
to
8246a67
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! The atomic logic reads as correct to me
8246a67
to
41961af
Compare
I got a CI failure on rebase that seems legit:
It seems we're rebuilding an object shape during compaction. Not sure exactly when happened, but I suppose |
Whenever we run into an inline cache miss when we try to set an ivar, we may need to take the global lock, just to be able to lookup inside `shape->edges`. To solve that, when we're in multi-ractor mode, we can treat the `shape->edges` as immutable. When we need to add a new edge, we first copy the table, and then replace it with CAS. This increases memory allocations, however we expect that creating new transitions becomes increasingly rare over time. ```ruby class A def initialize(bool) @A = 1 if bool @b = 2 else @c = 3 end end def test @d = 4 end end def bench(iterations) i = iterations while i > 0 A.new(true).test A.new(false).test i -= 1 end end if ARGV.first == "ractor" ractors = 8.times.map do Ractor.new do bench(20_000_000 / 8) end end ractors.each(&:take) else bench(20_000_000) end ``` The above benchmark takes 27 seconds in Ractor mode on Ruby 3.4, and only 1.7s with this branch. Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com>
41961af
to
1bce8ca
Compare
It seems I was right. For now I made it so these objects are pinned, which fixes the issue. That's not ideal, but I have no better solution short term. My hope however is that if we move on with #13289, ultimately there would be no But that's multiple big "ifs". |
Whenever we run into an inline cache miss when we try to set an ivar, we may need to take the global lock, just to be able to lookup inside
shape->edges
.To solve that, when we're in multi-ractor mode, we can treat the
shape->edges
as immutable. When we need to add a new edge, we first copy the table, and then replace it with CAS.This increases memory allocations, however we expect that creating new transitions becomes increasingly rare over time.
The above benchmark takes 27 seconds in Ractor mode on Ruby 3.4, and only 1.7s with this branch.
cc @etiennebarrie @jhawthorn @tenderlove @luke-gruber