No Speed Improvement with Spawn Multithreading?

I compiled a multithreaded version that runs the calculation twice using ‘spawn’ and ‘-Dpreview_mt’, in order to test whether CPU-intensive tasks can be accelerated by ‘spawn’. The result was that compared to synchronous computation once, the multithreaded computation twice did not improve efficiency. However, the CPU utilization did indeed exceed 100%.

channel = Channel(UInt32).new


def fib(n : UInt32) : UInt32
  if n <= 1 
    n
  else
    fib(n-1) + fib(n-2)
  end
end


number = ARGV[0].to_u32

spawn do 
  channel.send(fib(number))
end

spawn do
  channel.send(fib(number))
end


res_1 = channel.receive
res_2 = channel.receive

puts "#{res_1} #{res_2}"  

time -v output:

[I] ~/d/crystal ❯❯❯ gtime ./hello_twice.exe 42
267914296 267914296
12.51user 0.07system 0:06.95elapsed 181%CPU (0avgtext+0avgdata 2136maxresident)k
0inputs+0outputs (0major+665minor)pagefaults 0swaps
[I] ~/d/crystal ❯❯❯ gtime ./hello.exe 42
267914296
4.95user 0.47system 0:06.02elapsed 90%CPU (0avgtext+0avgdata 1868maxresident)k
0inputs+0outputs (3major+591minor)pagefaults 0swaps

Welcome to the forums, anzhi0708!

Maybe I’m reading it wrong, but it looks like you were able to perform two Fibonacci calculations with the multi threaded approach in the same time (ish) as it took to calculate one Fibonacci calculations with the single threaded? That sounds like you doubled your efficiency :slight_smile:

1 Like

Oh my, I didn’t know that ‘elapsed’ was the total runtime of the program. I thought the first item, ‘user’, was the total time. Thank you for your response! I apologize for the misunderstanding, I’m a beginner.

1 Like

You can double check buy building hello_twice without -Dpreview_mt: It still runs two calculations in two fibers, but on the same thread and thus takes twice as long to execute.

Also, in case you’re not aware, when comparing runtime performance, it’s usually best to build with --release in order to get most optimized code.