I have a server that's primarily running a Ruby script. Because Ruby (2.7) has a GIL, it is single threaded.
My computer (server) has an Intel i3 dual core processor, but due to hyperthreading I see 4 cores. Ruby only utilizes 25% CPU under heavy load. I wanted to see if disabling hyperthreading benefits a programming language that runs on single thread.
Also, my server is running a very minimal desktop environment and it doesn't use more than 2% CPU. So I wanted to make most of the resources available to Ruby. I did a benchmark to see if I really get any performance boost by disabling hyperthreading.
Benchmark:
I wrote a simple Ruby script that runs a while loop and adds a the value of the loop counter with another variable. This program should use 100% of a CPU core:
#!/usr/bin/env ruby $-v = true LOOPS = ENV['N'].to_i.then { |x| x < 1 ? 100_000_000 : x } + 1 i, j, t = 0, 0, Time.now puts "Counting till #{LOOPS - 1} and adding values to V..." while (i += 1) < LOOPS if i % 10000 == 0 e = Time.now - t r = LOOPS.*(e)./(i).-(e).round(2) print "\e[2KN: #{i} | Done: #{i.*(100) / LOOPS}% | Elapsed: #{e.round(2)}s | Estimated Rem: #{r}s\r" end j += i end puts "\nV = #{j}\nTime: #{(Time.now).-(t).round(2)}s" - With Hyperthreading:
⮚ ruby p.rb Counting till 100000000 and adding values to V... N: 100000000 | Done: 99% | Elapsed: 4.55s | Estimated Rem: 0.0s V = 5000000050000000 Time: 4.55s ⮚ ruby p.rb Counting till 100000000 and adding values to V... N: 100000000 | Done: 99% | Elapsed: 4.54s | Estimated Rem: 0.0s V = 5000000050000000 Time: 4.54s ⮚ ruby p.rb Counting till 100000000 and adding values to V... N: 100000000 | Done: 99% | Elapsed: 4.67s | Estimated Rem: 0.0s V = 5000000050000000 Time: 4.67s gnome-system-monitor reported 25% CPU usage by Ruby while the test was running.
- Without Hyperthreading:
[ # echo 0 | tee /sys/devices/system/cpu/cpu{2,3}/online used to disable hyperthreads ]
⮚ ruby p.rb Counting till 100000000 and adding values to V... N: 100000000 | Done: 99% | Elapsed: 4.72s | Estimated Rem: 0.0s V = 5000000050000000 Time: 4.72s ⮚ ruby p.rb Counting till 100000000 and adding values to V... N: 100000000 | Done: 99% | Elapsed: 4.54s | Estimated Rem: 0.0s V = 5000000050000000 Time: 4.54s ⮚ ruby p.rb Counting till 100000000 and adding values to V... N: 100000000 | Done: 99% | Elapsed: 4.56s | Estimated Rem: 0.0s V = 5000000050000000 Time: 4.56s gnome-system-monitor reported 50% CPU usage by Ruby while the test was running.
I have even ran the test on my laptop, which takes around twice the time it took on my computer. But the result is identical: disabling hyperthreading doesn't help the process to do better. And even worse, my laptop gets a bit slower when multitasking.
So in the non-hyperthreading mode, Ruby used 2x the CPU power compared to the hyperthreaded mode. But why did it still take the same amount of time to complete the same task?
echo 0 | tee /sys/devices/system/cpu/cpu{2,3}/onlineused to disable hyperthreads" - Are you sure that correctly disables hyperthreading? You might have reduced yourself to a single core with HT, instead of two cores without HT.