RubyConf 2024: Code and Perfetto links for "How the Ruby Global VM Lock impacts app performance"
Hello! This page collects the code examples and perfetto visualization links for the How the Ruby Global VM Lock impacts app performance RubyConf 2024 talk.
Observing the GVL #1
Click Open Example 1 to explore this example. Alternatively, download rc-example1.json.gz and open it with the Perfetto UI. Example code is from rc-example1.rb:
require "gvl-tracing"
def counter_loop
counter = 0
counter += 1 while counter < 1_000_000_000
end
GvlTracing.start("rc-example1.json") do
t2 = Thread.new { counter_loop }
counter_loop
t2.join
end
Observing the GVL #2
Click Open Example 2 to explore this example. Alternatively, download rc-example2.json.gz and open it with the Perfetto UI. Example code is from rc-example2.rb:
require "gvl-tracing"
def counter_loop
counter = 0
counter += 1 while counter < 100_000_000
end
GvlTracing.start("rc-example2.json", os_threads_view_enabled: true) do
threads = 9.times.map { Thread.new { counter_loop } }
counter_loop
threads.map(&:join)
end
Observing the GVL #3
Click Open Example 3 to explore this example. Alternatively, download rc-example3.json.gz and open it with the Perfetto UI. Example code is from rc-example3.rb:
require "gvl-tracing"
def counter_loop
counter = 0
counter += 1 while counter < 100_000_000
end
GvlTracing.start("rc-example3.json") do
Thread.new {
counter_loop
sleep
}
3.times { counter_loop }
end
Observing the GVL #4
Click Open Example 4 to explore this example. Alternatively, download rc-example4.json.gz and open it with the Perfetto UI. Example code is from rc-example4.rb:
require "gvl-tracing"
require "net/http"
def perform_request =
Net::HTTP.start("www.google.com", open_timeout: 0.5, read_timeout: 0.5, write_timeout: 0.5) { |it| it.get("/") }
GvlTracing.start("rc-example4.json") do
20.times { perform_request }
end
Observing the GVL #5
Click Open Example 5 to explore this example. Alternatively, download rc-example5.json.gz and open it with the Perfetto UI. Example code is from rc-example5.rb:
require "gvl-tracing"
require "net/http"
require "benchmark/ips"
def perform_request =
Net::HTTP.start("www.google.com", open_timeout: 0.5, read_timeout: 0.5, write_timeout: 0.5) { |it| it.get("/") }
GvlTracing.start("rc-example5.json") do
Benchmark.ips do |x|
x.config(time: 1, warmup: 0)
x.report("request") { perform_request }
end
end
Observing the GVL #6
Click Open Example 6 to explore this example. Alternatively, download rc-example6.json.gz and open it with the Perfetto UI. Example code is from rc-example6.rb:
require "gvl-tracing"
require "net/http"
require "benchmark/ips"
def perform_request =
Net::HTTP.start("www.google.com", open_timeout: 0.5, read_timeout: 0.5, write_timeout: 0.5) { |it| it.get("/") }
def counter_loop
counter = 0
counter += 1 while counter < 1_000_000_000
end
GvlTracing.start("rc-example6.json") do
Thread.new { counter_loop }
Benchmark.ips do |x|
x.config(time: 1, warmup: 0)
x.report("request") { perform_request }
end
end
Observing the GVL #7 (Ruby 3.2)
Click Open Example 7 to explore this example. Alternatively, download rc-example7.json.gz and open it with the Perfetto UI. Example code is from rc-example7.rb:
require "gvl-tracing"
require "net/http"
require "benchmark/ips"
def perform_request =
Net::HTTP.start("www.google.com", open_timeout: 0.5, read_timeout: 0.5, write_timeout: 0.5) { |it| it.get("/") }
def counter_loop
counter = 0
counter += 1 while counter < 1_000_000_000
end
GvlTracing.start("rc-example7.json") do
Ractor.new { counter_loop }
Benchmark.ips do |x|
x.config(time: 1, warmup: 0)
x.report("request") { perform_request }
end
end
Click Open Example 7-2 to explore this example. Alternatively, download rc-example7-2.json.gz and open it with the Perfetto UI. Example code is from rc-example7-2.rb:
require "gvl-tracing"
def counter_loop
counter = 0
counter += 1 while counter < 100_000_000
end
GvlTracing.start("rc-example7-2.json", os_threads_view_enabled: true) do
ractors = 9.times.map { Ractor.new { counter_loop } }
counter_loop
ractors.map(&:take)
end
Observing the GVL #7 (Ruby 3.3+)
Example code for both of the following is from rc-example7-2.rb, same as above; the difference is that we’re running the examples on either Ruby 3.3 or Ruby 3.4 (the latter using RUBY_MAX_CPU=4
).
Click Open Example 7-2-r33 to explore this example. Alternatively, download rc-example7-2-r33.json.gz and open it with the Perfetto UI.
Click Open Example 7-2-max-cpu-4 to explore this example. Alternatively, download rc-example7-2-max-cpu-4.json.gz and open it with the Perfetto UI.
Observing the GVL #8
Click Open Example 8 to explore this example. Alternatively, download rc-example2-mn-threads.json.gz and open it with the Perfetto UI. Example code is from rc-example2.rb (Same as above, the only difference is running it with RUBY_MN_THREADS=1
):
require "gvl-tracing"
def counter_loop
counter = 0
counter += 1 while counter < 100_000_000
end
GvlTracing.start("rc-example2.json", os_threads_view_enabled: true) do
threads = 9.times.map { Thread.new { counter_loop } }
counter_loop
threads.map(&:join)
end
Further exploration
If this topic interests you, I suggest looking at my two other blog posts on the subject:
talk to me about this post: ivo@
this domain / twitter
interested in my blog? get notified of new posts via email
around/visiting london? would love to meet up!