mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
Make setting and accessing class ivars lock-free
Now that class fields have been deletated to a T_IMEMO/class_fields when we're in multi-ractor mode, we can read and write class instance variable in an atomic way using Read-Copy-Update (RCU). Note when in multi-ractor mode, we always use RCU. In theory we don't need to, instead if we ensured the field is written before the shape is updated it would be safe. Benchmark: ```ruby Warning[:experimental] = false class Foo @foo = 1 @bar = 2 @baz = 3 @egg = 4 @spam = 5 class << self attr_reader :foo, :bar, :baz, :egg, :spam end end ractors = 8.times.map do Ractor.new do 1_000_000.times do Foo.bar + Foo.baz * Foo.egg - Foo.spam end end end if Ractor.method_defined?(:value) ractors.each(&:value) else ractors.each(&:take) end ``` This branch vs Ruby 3.4: ```bash $ hyperfine -w 1 'ruby --disable-all ../test.rb' './miniruby ../test.rb' Benchmark 1: ruby --disable-all ../test.rb Time (mean ± σ): 3.162 s ± 0.071 s [User: 2.783 s, System: 10.809 s] Range (min … max): 3.093 s … 3.337 s 10 runs Benchmark 2: ./miniruby ../test.rb Time (mean ± σ): 208.7 ms ± 4.6 ms [User: 889.7 ms, System: 6.9 ms] Range (min … max): 202.8 ms … 222.0 ms 14 runs Summary ./miniruby ../test.rb ran 15.15 ± 0.47 times faster than ruby --disable-all ../test.rb ```
This commit is contained in:
parent
8b5ac5abf2
commit
a74c385208
Notes:
git
2025-06-12 12:55:26 +00:00
4 changed files with 92 additions and 83 deletions
|
@ -531,13 +531,6 @@ RCLASS_WRITABLE_ENSURE_FIELDS_OBJ(VALUE obj)
|
|||
return ext->fields_obj;
|
||||
}
|
||||
|
||||
static inline void
|
||||
RCLASSEXT_SET_FIELDS_OBJ(VALUE obj, rb_classext_t *ext, VALUE fields_obj)
|
||||
{
|
||||
RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
|
||||
RB_OBJ_WRITE(obj, &ext->fields_obj, fields_obj);
|
||||
}
|
||||
|
||||
static inline VALUE
|
||||
RCLASS_WRITABLE_FIELDS_OBJ(VALUE obj)
|
||||
{
|
||||
|
@ -545,6 +538,16 @@ RCLASS_WRITABLE_FIELDS_OBJ(VALUE obj)
|
|||
return RCLASSEXT_FIELDS_OBJ(RCLASS_EXT_WRITABLE(obj));
|
||||
}
|
||||
|
||||
static inline void
|
||||
RCLASSEXT_SET_FIELDS_OBJ(VALUE obj, rb_classext_t *ext, VALUE fields_obj)
|
||||
{
|
||||
RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
|
||||
|
||||
VALUE old_fields_obj = ext->fields_obj;
|
||||
RUBY_ATOMIC_VALUE_SET(ext->fields_obj, fields_obj);
|
||||
RB_OBJ_WRITTEN(obj, old_fields_obj, fields_obj);
|
||||
}
|
||||
|
||||
static inline void
|
||||
RCLASS_WRITABLE_SET_FIELDS_OBJ(VALUE obj, VALUE fields_obj)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue