Feature #19355
openAdd finer coarsed locking for searching callable method entries
Description
During multi-ractor mode, unfortunately when calling methods often there's a call to the internal cruby function callable_method_entry
, which
returns a cached CME or a new one. In the case that it's cached, there's a VM lock around its access that could be reduced to a lock
pertaining to the class of the caller of the method. This reduces locking in multi-ractor mode and allows, for example, object allocation to happen
at the same time as method calls.
Updated by luke-gru (Luke Gruber) almost 2 years ago
MyClass = Object
class MyClass2 < Object;
def call_a_method
[]
end
def call_another_method
{}
end
end
USE_RACTORS = ARGV.first == "ractor"
puts "ractors: #{USE_RACTORS ? 't' : 'f'}"
class FakeRactor
def initialize
yield
self
end
def take
end
end
def concurrency(&blk)
if USE_RACTORS
Ractor.new(&blk)
else
FakeRactor.new(&blk)
end
end
bench = Benchmark.measure do
rs = []
100.times do
rs << concurrency do
50_000.times do|i|
obj = MyClass.new
obj.respond_to?(:hi)
obj2 = MyClass2.new
obj2.respond_to?(:hi)
obj2.call_a_method
obj2.call_another_method
end
end
end
rs.each(&:take)
end
puts bench
On my machine without my local patch, it takes 6.5 seconds and with the patch 5.5 seconds.
Of course storing a mutex on every class instance takes more memory so it might not be worth
it But with this new mutex it's possible also to do constant lookup / update without the VM
lock too.