konnigun
konnigun

Reputation: 1805

Why does this multithreaded program not work as intended?

I wrote a test program. In short, it does the following:

  1. executes some random useless calcuations (but long enough) in single thread and prints execution time
  2. executes same program in 6 threads and prints execution time

Now, in both cases execution time is the same. What am I doing wrong?
Here are the sources:

def time
  start = Time.now
  yield
  p Time.now - start
end


range_limit = 9999
i_exponent = 9999

time do
  array = (1 .. range_limit).map { |i | i**i_exponent }
  p (array.inject(:+)/2)[0]
end

time do
  first_thread = Thread.new do
    arr = (1..range_limit/6).map { |i| i**i_exponent }
    arr.inject(:+)
  end

  second_thread = Thread.new do
    arr = (range_limit/6..range_limit*2/6).map { |i| i**i_exponent }
    arr.inject(:+)
  end

  third_thread = Thread.new do
    arr = (range_limit*2/6..range_limit*3/6).map { |i| i**i_exponent }
    arr.inject(:+)
    end

  fourth_thread = Thread.new do
    arr = (range_limit*3/6..range_limit*4/6).map { |i| i**i_exponent }
    arr.inject(:+)
    end

  fifth_thread = Thread.new do
    arr = (range_limit*4/6..range_limit*5/6).map { |i| i**i_exponent }
    arr.inject(:+)
  end

  sixth_thread = Thread.new do
    arr = (range_limit*5/6..range_limit).map { |i| i**i_exponent }
    arr.inject(:+)
  end

  first_thread.join
  second_thread.join
  third_thread.join
  fourth_thread.join
  fifth_thread.join
  sixth_thread.join

  result = first_thread.value + second_thread.value + third_thread.value + fifth_thread.value + sixth_thread.value

  p (result/2)[0]
end

Upvotes: 0

Views: 57

Answers (1)

user4815162342
user4815162342

Reputation: 154946

Interpreters like Ruby and Python are not truly parallel while executing multiple threads - to protect the state of the interpreter, they have a global VM lock that doesn't allow simultaneous execution.

To get the benefit of threads, you need to find a way to execute non-Ruby code that runs without the global lock, use multiple processes instead of threads. Another option is to switch to a ruby implementation that doesn't have the global lock, such as JRuby or Rubinius.

Upvotes: 1

Related Questions