ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:108246] [Ruby master Bug#18733] Ruby always using Performance Cores with Apple M1
@ 2022-04-15  5:04 jakit (Jakit Liang)
  2022-04-15  5:42 ` [ruby-core:108248] " ko1 (Koichi Sasada)
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: jakit (Jakit Liang) @ 2022-04-15  5:04 UTC (permalink / raw)
  To: ruby-core

Issue #18733 has been reported by jakit (Jakit Liang).

----------------------------------------
Bug #18733: Ruby always using Performance Cores with Apple M1
https://bugs.ruby-lang.org/issues/18733

* Author: jakit (Jakit Liang)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [arm64-darwin21]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
Code:

```
require 'benchmark'

def fib(n)
  return n if [0,1].include?(n)
  fib(n-1) + fib(n-2)
end

tp = []

puts Benchmark.measure {
  8.times do
    tp << fork { fib(37) }
  end

  tp.each { |t| Process.wait(t) }
}

puts Benchmark.measure {
  8.times.map {
    Ractor.new { fib(37) }
  }.each{ |r| r.take }
}
```

Result:

|A |B |
|--|--|
| fork | 0.000264   0.003439  87.181198 ( 11.211349) |
| Ractor | 80.292916  15.062559  95.355475 ( 39.569527) |

And I found that here's the problem showing on the ActiveMonitor.app:

![ruby_bug_with_m1](http://jakit.cn/screen_shot_ruby_bug.jpg)

As you can see, the process of ruby is always using all Performance Cores on my Apple M1 Mac.

But there's no one of the Efficiency Cores was in used by ruby Ractor.




-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:108248] [Ruby master Bug#18733] Ruby always using Performance Cores with Apple M1
  2022-04-15  5:04 [ruby-core:108246] [Ruby master Bug#18733] Ruby always using Performance Cores with Apple M1 jakit (Jakit Liang)
@ 2022-04-15  5:42 ` ko1 (Koichi Sasada)
  2022-04-15  6:22 ` [ruby-core:108249] [Ruby master Bug#18733] Ruby GC problems cause performance issue with Ractor jakit (Jakit Liang)
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: ko1 (Koichi Sasada) @ 2022-04-15  5:42 UTC (permalink / raw)
  To: ruby-core

Issue #18733 has been updated by ko1 (Koichi Sasada).


Thank you for your report.

On my WSL2 environment with 12 cores, `ruby 3.2.0dev (2022-04-15T04:24:48Z master 92614111c0) [x86_64-linux]` shows worse results.

```
  0.003304   0.000000 102.404055 ( 13.083221)
296.139861 262.090810 558.230671 (278.664518)
```

However, I modified it with 

```ruby
def fib(n)
  return n if n < 2 # `[0,1].include?(n)` generates an Array object
  fib(n-1) + fib(n-2)
end
```

it shows

```
  0.000000   0.003886  31.579734 (  4.092415)
 31.779964   0.003833  31.783797 (  4.114323)
```

maybe because of object allocation (GC) causes contention and the system determines it should not use performance cores.
(BTW I can't see figure "ruby_bug_with_m1")

The conclusion is, the reason of this issue is the implementation of object allocation (GC).


----------------------------------------
Bug #18733: Ruby always using Performance Cores with Apple M1
https://bugs.ruby-lang.org/issues/18733#change-97265

* Author: jakit (Jakit Liang)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [arm64-darwin21]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
Code:

```
require 'benchmark'

def fib(n)
  return n if [0,1].include?(n)
  fib(n-1) + fib(n-2)
end

tp = []

puts Benchmark.measure {
  8.times do
    tp << fork { fib(37) }
  end

  tp.each { |t| Process.wait(t) }
}

puts Benchmark.measure {
  8.times.map {
    Ractor.new { fib(37) }
  }.each{ |r| r.take }
}
```

Result:

|A |B |
|--|--|
| fork | 0.000264   0.003439  87.181198 ( 11.211349) |
| Ractor | 80.292916  15.062559  95.355475 ( 39.569527) |

And I found that here's the problem showing on the ActiveMonitor.app:

![ruby_bug_with_m1](http://jakit.cn/screen_shot_ruby_bug.jpg)

As you can see, the process of ruby is always using all Performance Cores on my Apple M1 Mac.

But there's no one of the Efficiency Cores was in used by ruby Ractor.




-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:108249] [Ruby master Bug#18733] Ruby GC problems cause performance issue with Ractor
  2022-04-15  5:04 [ruby-core:108246] [Ruby master Bug#18733] Ruby always using Performance Cores with Apple M1 jakit (Jakit Liang)
  2022-04-15  5:42 ` [ruby-core:108248] " ko1 (Koichi Sasada)
@ 2022-04-15  6:22 ` jakit (Jakit Liang)
  2022-04-15  9:13 ` [ruby-core:108255] " Mark24 (Yang Zhang)
  2025-07-03  0:05 ` [ruby-core:122646] [Ruby Bug#18733] Heavy GC allocations " jhawthorn (John Hawthorn) via ruby-core
  3 siblings, 0 replies; 5+ messages in thread
From: jakit (Jakit Liang) @ 2022-04-15  6:22 UTC (permalink / raw)
  To: ruby-core

Issue #18733 has been updated by jakit (Jakit Liang).


Thanks much! :)

And I change the topic to GC problem instead problem of m1.

Hope the memory management will get improvement. ;)

ko1 (Koichi Sasada) wrote in #note-1:
> Thank you for your report.
> 
> On my WSL2 environment with 12 cores, `ruby 3.2.0dev (2022-04-15T04:24:48Z master 92614111c0) [x86_64-linux]` shows worse results.
> 
> ```
>   0.003304   0.000000 102.404055 ( 13.083221)
> 296.139861 262.090810 558.230671 (278.664518)
> ```
> 
> However, I modified it with 
> 
> ```ruby
> def fib(n)
>   return n if n < 2 # `[0,1].include?(n)` generates an Array object
>   fib(n-1) + fib(n-2)
> end
> ```
> 
> it shows
> 
> ```
>   0.000000   0.003886  31.579734 (  4.092415)
>  31.779964   0.003833  31.783797 (  4.114323)
> ```
> 
> maybe because of object allocation (GC) causes contention and the system determines it should not use performance cores.
> (BTW I can't see figure "ruby_bug_with_m1")
> 
> The conclusion is, the reason of this issue is the implementation of object allocation (GC).



----------------------------------------
Bug #18733: Ruby GC problems cause performance issue with Ractor
https://bugs.ruby-lang.org/issues/18733#change-97267

* Author: jakit (Jakit Liang)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [arm64-darwin21]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
Code:

```
require 'benchmark'

def fib(n)
  return n if [0,1].include?(n)
  fib(n-1) + fib(n-2)
end

tp = []

puts Benchmark.measure {
  8.times do
    tp << fork { fib(37) }
  end

  tp.each { |t| Process.wait(t) }
}

puts Benchmark.measure {
  8.times.map {
    Ractor.new { fib(37) }
  }.each{ |r| r.take }
}
```

Result:

|A |B |
|--|--|
| fork | 0.000264   0.003439  87.181198 ( 11.211349) |
| Ractor | 80.292916  15.062559  95.355475 ( 39.569527) |

And I found that here's the problem showing on the ActiveMonitor.app:

![ruby_bug_with_m1](http://jakit.cn/screen_shot_ruby_bug.jpg)

As you can see, the process of ruby is always using all Performance Cores on my Apple M1 Mac.

But there's no one of the Efficiency Cores was in used by ruby Ractor.




-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:108255] [Ruby master Bug#18733] Ruby GC problems cause performance issue with Ractor
  2022-04-15  5:04 [ruby-core:108246] [Ruby master Bug#18733] Ruby always using Performance Cores with Apple M1 jakit (Jakit Liang)
  2022-04-15  5:42 ` [ruby-core:108248] " ko1 (Koichi Sasada)
  2022-04-15  6:22 ` [ruby-core:108249] [Ruby master Bug#18733] Ruby GC problems cause performance issue with Ractor jakit (Jakit Liang)
@ 2022-04-15  9:13 ` Mark24 (Yang Zhang)
  2025-07-03  0:05 ` [ruby-core:122646] [Ruby Bug#18733] Heavy GC allocations " jhawthorn (John Hawthorn) via ruby-core
  3 siblings, 0 replies; 5+ messages in thread
From: Mark24 (Yang Zhang) @ 2022-04-15  9:13 UTC (permalink / raw)
  To: ruby-core

Issue #18733 has been updated by Mark24 (Yang Zhang).


One problem I found was that when I ran the same script on different Ruby versions, there was performance gap between them.


``` ruby
require 'benchmark'

def fib(n)
  return n if n < 2
  fib(n-1) + fib(n-2)
end

puts Benchmark.measure {
  8.times.map {
    Ractor.new{ fib(38) }
  }.each{|r| r.take}
}

```


```
# Device Mac mini (M1, 2020) 

# ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [arm64-darwin21]
# 33.873394   0.143453  34.016847 (  4.727655)
# 33.749938   0.153633  33.903571 (  4.749335)
# 34.343544   0.168297  34.511841 (  4.846679)
# 33.873749   0.148050  34.021799 (  4.753797)
# 34.144618   0.177153  34.321771 (  4.861416)

# time avg: 4.7877764

# ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [arm64-darwin21]
# 43.994316   0.224457  44.218773 (  6.309634)
# 44.265488   0.192328  44.457816 (  6.124617)
# 44.194585   0.215987  44.410572 (  6.195150)
# 43.846945   0.219032  44.065977 (  6.259834)
# 44.076493   0.213183  44.289676 (  6.234526)

# time avg: 6.224752199999999

# ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [arm64-darwin21]
# 43.657412   0.241501  43.898913 (  6.385710)
# 43.986863   0.230514  44.217377 (  6.370350)
# 43.737608   0.233663  43.971271 (  6.370617)
# 44.182188   0.210544  44.392732 (  6.197169)
# 43.907983   0.239740  44.147723 (  6.278601) 

# time avg: 6.3204894000000005
```



## 5 times avg used time

|name   |   avg times  | compare|
|-------|-----|-------|
|ruby310  | 4.7877764   |100%|
|ruby311  | 6.2247522   |130%|
|ruby312  | 6.3204894   |132%|

Maybe this could some help.


----------------------------------------
Bug #18733: Ruby GC problems cause performance issue with Ractor
https://bugs.ruby-lang.org/issues/18733#change-97272

* Author: jakit (Jakit Liang)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [arm64-darwin21]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
Code:

```
require 'benchmark'

def fib(n)
  return n if [0,1].include?(n)
  fib(n-1) + fib(n-2)
end

tp = []

puts Benchmark.measure {
  8.times do
    tp << fork { fib(37) }
  end

  tp.each { |t| Process.wait(t) }
}

puts Benchmark.measure {
  8.times.map {
    Ractor.new { fib(37) }
  }.each{ |r| r.take }
}
```

Result:

|A |B |
|--|--|
| fork | 0.000264   0.003439  87.181198 ( 11.211349) |
| Ractor | 80.292916  15.062559  95.355475 ( 39.569527) |

And I found that here's the problem showing on the ActiveMonitor.app:

![ruby_bug_with_m1](http://jakit.cn/screen_shot_ruby_bug.jpg)

As you can see, the process of ruby is always using all Performance Cores on my Apple M1 Mac.

But there's no one of the Efficiency Cores was in used by ruby Ractor.




-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ruby-core:122646] [Ruby Bug#18733] Heavy GC allocations cause performance issue with Ractor
  2022-04-15  5:04 [ruby-core:108246] [Ruby master Bug#18733] Ruby always using Performance Cores with Apple M1 jakit (Jakit Liang)
                   ` (2 preceding siblings ...)
  2022-04-15  9:13 ` [ruby-core:108255] " Mark24 (Yang Zhang)
@ 2025-07-03  0:05 ` jhawthorn (John Hawthorn) via ruby-core
  3 siblings, 0 replies; 5+ messages in thread
From: jhawthorn (John Hawthorn) via ruby-core @ 2025-07-03  0:05 UTC (permalink / raw)
  To: ruby-core; +Cc: jhawthorn (John Hawthorn)

Issue #18733 has been updated by jhawthorn (John Hawthorn).

Subject changed from Ruby GC problems cause performance issue with Ractor to Heavy GC allocations cause performance issue with Ractor

This performance gap no longer exists on master. Benchmark from my Ryzen 7 3700X running linux:

```
❯ ruby -v
ruby 3.4.4 (2025-05-14 revision a38531fd3f) +PRISM [x86_64-linux]

❯ RUBY_MAX_CPU=16 ruby test.rb
  0.000000   0.003827  19.434401 (  2.459187)
test.rb:20: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
176.949877   0.005083 176.954960 ( 22.663767)
```

```
❯ ruby -v
ruby 3.5.0dev (2025-07-02T20:01:24Z master d5f5a56bf2) +PRISM [x86_64-linux]

❯ RUBY_MAX_CPU=16 ruby test.rb
  0.000477   0.003464  20.087896 (  2.532730)
test.rb:20: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
 20.272416   0.001401  20.273817 (  2.576483)
```

I get similar results on my M4 macbook pro

A part of this is because `[0,1].include?(x)` no longer allocates (https://github.com/ruby/ruby/commit/1dd40ec18a55ff46f52d0ba44ff5d7923f57c08f), but that was also the case in Ruby 3.4.

Modifying the benchmark to use `[0,1].itself.include?(x)` to avoid eliding the Array we can still reproduce the original issue, though it's clear we are making progress.

``` ruby
require 'benchmark'

def fib(n)
  return n if [0,1].itself.include?(n)
  fib(n-1) + fib(n-2)
end

tp = []

puts Benchmark.measure {
  8.times do
    tp << fork { fib(37) }
  end

  tp.each { |t| Process.wait(t) }
}

puts Benchmark.measure {
  8.times.map {
    Ractor.new { fib(37) }
  }.each(&:join)
}
```

```
❯ RUBY_MAX_CPU=16 ruby test.rb
  0.000048   0.004020  53.875052 (  6.815713)
test.rb:20: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
123.640647  27.657227 151.297874 ( 42.308539)
```

I've uploaded a profile here https://share.firefox.dev/44w9adY. We can see that the additional time is spent in GC (sweeping or joining the barrier from a GC step another Ractor initiated)

----------------------------------------
Bug #18733: Heavy GC allocations cause performance issue with Ractor
https://bugs.ruby-lang.org/issues/18733#change-113922

* Author: jakit (Jakit Liang)
* Status: Assigned
* Assignee: ractor
* ruby -v: ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [arm64-darwin21]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
Code:

```
require 'benchmark'

def fib(n)
  return n if [0,1].include?(n)
  fib(n-1) + fib(n-2)
end

tp = []

puts Benchmark.measure {
  8.times do
    tp << fork { fib(37) }
  end

  tp.each { |t| Process.wait(t) }
}

puts Benchmark.measure {
  8.times.map {
    Ractor.new { fib(37) }
  }.each{ |r| r.take }
}
```

Result:

|A |B |
|--|--|
| fork | 0.000264   0.003439  87.181198 ( 11.211349) |
| Ractor | 80.292916  15.062559  95.355475 ( 39.569527) |

And I found that here's the problem showing on the ActiveMonitor.app:

![ruby_bug_with_m1](http://jakit.cn/screen_shot_ruby_bug.jpg)

As you can see, the process of ruby is always using all Performance Cores on my Apple M1 Mac.

But there's no one of the Efficiency Cores was in used by ruby Ractor.




-- 
https://bugs.ruby-lang.org/
______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-07-03  0:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-15  5:04 [ruby-core:108246] [Ruby master Bug#18733] Ruby always using Performance Cores with Apple M1 jakit (Jakit Liang)
2022-04-15  5:42 ` [ruby-core:108248] " ko1 (Koichi Sasada)
2022-04-15  6:22 ` [ruby-core:108249] [Ruby master Bug#18733] Ruby GC problems cause performance issue with Ractor jakit (Jakit Liang)
2022-04-15  9:13 ` [ruby-core:108255] " Mark24 (Yang Zhang)
2025-07-03  0:05 ` [ruby-core:122646] [Ruby Bug#18733] Heavy GC allocations " jhawthorn (John Hawthorn) via ruby-core

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).