Ruby 3.0 Ractors performance test strange results

I need to distribute some massive work like checksums/encryption between CPU cores.

Here is my simple test:

require 'digest/sha2'

N = 1_500_000

def workload
	N.times do |n|
		Digest::SHA2.base64digest(n.to_s)
	end
end

puts 'in the main thread'
t_start = Time.now
	workload
puts "Total: %.3f" % (Time.now - t_start)
puts


worker1 = Ractor.new do
	Ractor.receive
	print '['; workload; ']'
end
worker2 = Ractor.new do
	Ractor.receive
	print '['; workload; ']'
end

puts 'in 2 ractors'
t_start = Time.now
	worker1.send 'start'
	worker2.send 'start'
	print '='
	print worker1.take
	print worker2.take
puts
puts "Total: %.3f" % (Time.now - t_start)

I can clearly see how 2 CPU cores are loaded using Ractors but performance is so strange:

On Linux VPS:
7.7s — workload in the main thread
10s (+30%) — in 1 Ractor (same workload) — expected this to be close to 7.7
32s — in 2 Ractors (each have same workload) — expected this to be close to 7.7

4-core CPU 2.6GHz
CentOS 7.9
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]

On Windows 10:
6.5s — in the main thread
9s (+38%) — in 1 Ractor
11s — in 2 Ractors — not so bad, seems to be faster than same 2 workloads in the main thread.

2-core CPU 3.6GHz
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x64-mingw32]

Is it really the current state of the Ractors performance or am I missing something?

Although the systems are different. There’s a catch. So the free VPS solutions gives you a container with shared CPU. And the CPU can be under different loads. If you want to see that in action, I have used a gem called LinuxStat with one of my rails app.

If you open this app:

You can see the total CPU usages

And the CPU usage by the current process ($$)

As in the image, you can see, the server is under 100% CPU usage right now.

If you go to the home page, and start calculating 20K digits of Pi, you will see the time is too long when the system is under 100% load. I have also noticed that in the night at around 8:00 - 9:00 PM (in IST), the systems are under lesser load, the CPU usage is like 10 - 20%, and calculating 20K digits of Pi takes less time.

So when you benchmark, you don’t know what’s the CPU usage of your system! And that could be a problem and you may see a lot of different results for your benchmarks…

Edit At night:

The server is under less load… But it always jumps… So it’s not great to benchmark on such systems… For benchmarking you may want to use a system with minimal background apps running, no GUI, no huge logs to terminal, and also perhaps a real-time kernel running as well.

You are right, testing inside VPS is a bad idea.
But in my case, I knew that the host machine was not loaded and I repeated the test many times and used some average results. And also I have tested on my local Windows machine — it also showed the issue.

Today I have added a post about the investigation results.

I too have seen strange results testing ractors. I used the code at Illustrates/Exercises Multi-CPU Usage in MRI Ruby Using Ractors · GitHub to do some arbitrary but predictable work. I have a 24-core Ryzen 9 CPU, and I compared using 1 ractor with using 24. With 24, htop reported that all 24 CPU’s were at 100% most of the time, yet the elapsed time using 24 CPU’s was only about a third less than when using 1 CPU. Also, the CPU’s seemed to be working collectively about ten times harder with 24 CPU’s. Here is the program output:

1 CPU:
Many HTOP readings are < 100% for all CPU's
 time ractor/my_ractor.rb ruby '*.rb'
Running the following command to find all filespecs to process: find -L ruby -type f -name '*.rb' -print
Processing 8218 files in 1 slices, whose sizes are:
[8218]
ractor/my_ractor.rb ruby '*.rb'  2513.90s user 6.75s system 99% cpu 42:03.01 total


24 CPU's:
% time ractor/my_ractor.rb ruby '*.rb' ; espeak finished
Running the following command to find all filespecs to process: find -L ruby -type f -name '*.rb' -print
Processing 8218 files in 24 slices, whose sizes are:
[343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 329]
ractor/my_ractor.rb ruby '*.rb'  22986.42s user 14.98s system 1134% cpu 33:47.96 total

(In the command, ruby refers to the directory in which I’ve cloned the Github Ruby repo.)

Thank you for sharing!
You can also add your results and code to this open issue, it should help with further performance tuning.

Done, thanks! I’ve moved my code to a Github repo instead of a gist: keithrbennett-ractor-test/my_ractor.rb at master · keithrbennett/keithrbennett-ractor-test · GitHub.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs