5

在此之后, Ruby 线程限制 - 也适用于任何语言

我试图了解为什么我的线程不起作用。一些答案很清楚,例如:

“..用 fork 创建 4 个子进程将利用你的 4 个内核”这将是我的最终方法,因为线程在我的情况下似乎不起作用。

还有这个:

“..Ruby MRI 线程本身并不能充分利用运行 Ruby 代码的多核 CPU。但这是否对您来说是个问题取决于线程在做什么。如果它们正在对其他线程进行长时间运行的 I/O 调用进程在同一台机器上,你会看到不需要单独进程的好处。线程和多处理作为主题即使是简单的事情也会变得非常复杂。大多数语言会在开箱即用的简单和困难方面做出一些妥协……”

考虑到第二个,我已经从我的代码中删除了所有处理,只留下了 I/O。

这里是:

beginning_time = Time.now
img_processor.load_image(frames_dir+"/frame_0001.png")
img_processor.load_image(frames_dir+"/frame_0002.png")
end_time = Time.now
puts "Time elapsed #{(end_time - beginning_time)*1000} milliseconds"

beginning_time = Time.now
for frame_index in 1..2
    greyscale_frames_threads << Thread.new(frame_index) { |frame_number| 
        puts "Loading Image #{frame_number}"
        img_processor.load_image(frames_dir+"/frame_%04d.png"%+frame_number)
    }
end

puts "Joining Threads"
greyscale_frames_threads.each { |thread| thread.join } #this blocks the main thread
end_time = Time.now
puts "Time elapsed #{(end_time - beginning_time)*1000} milliseconds"

我得到的是这个......

对于第一个非线程案例:

经过的时间 15561.358 毫秒

对于第二个螺纹案例:

经过的时间 15442.401 毫秒

好的,性能提升在哪里?我错过了什么吗?硬盘是否阻塞?我真的需要生成进程才能在 ruby​​ 中看到真正的并行性吗?

4

1 回答 1

7

我真的需要生成进程才能在 ruby​​ 中看到真正的并行性吗?

是的,我想是这样:

require 'timeout'
require 'digest'
require 'benchmark'

def do_stuff
  Digest::SHA256.new.digest "a" * 100_000_000
end

N = 10
Benchmark.bm(10) do |x|

  x.report("sequential") do
    N.times do
      do_stuff
    end
  end

  x.report("subprocess") do
    N.times do
      fork { do_stuff }
    end
    Process.waitall
  end

  x.report("thread") do
    threads = []
    N.times do
      threads << Thread.new { do_stuff }
    end
    threads.each(&:join)
  end

end

MRI 2.0.0 的结果:

                 user     system      total        real
sequential   3.200000   0.180000   3.380000 (  3.383322)
subprocess   0.000000   0.000000   6.600000 (  1.068517)
thread       3.290000   0.210000   3.500000 (  3.496207)

第一个块(顺序)运行do_stuff4 次,一个接一个,第二个块(子进程)运行在 4 个核心上,而第三个块(线程)运行在一个核心上。


如果您更改do_stuff为:

def do_stuff
  sleep(1)
end

结果不一样:

                 user     system      total        real
sequential   0.000000   0.000000   0.000000 ( 10.021893)
subprocess   0.000000   0.010000   0.080000 (  1.013693)
thread       0.000000   0.000000   0.000000 (  1.003463)
于 2013-06-19T12:34:01.823 回答