Mam taką zagwozdkę. Z tego co pamiętam, to YARV a zatem Ruby 1.9.1 miał mieć natywne wątki.
Taka funkcjonalność bardzo by mi się przydała, ponieważ ostatnio dostałem czterordzeniowy serwer na własny użytek i chciałem maksymalnie wykorzystać jego możliwości. Zacząłem zatem od testów i ku mojemu zaskoczeniu okazało się, że albo YARV nie implementuje natywnych wątków albo coś źle skonfigurowałem.
Żeby uniknąć wątpliwości przytaczam procedurę testową. Zainstalowałem Ruby 1.9.0 na Debianie z paczek oraz skompilowałem Ruby 1.9.1-p0 ze strony ruby-lang.org z opcją --enable-pthreads.
Test wyglądał następująco:
[code=ruby]def calc()
10000000.times{|i| i * i}
end
MAX_RUNS = ARGV[0] && ARGV[0].to_i || 5
def parallel(runs)
Benchmark.measure {
threads = []
runs.times{ threads << Thread.new{calc()} }
threads.each{|t| t.join}
}
end
def parallel_proc(runs)
Benchmark.measure {
pids = []
runs.times{
pid = fork
if pid
pids << pid
else
calc()
exit
end
}
pids.each{|pid| Process.wait(pid) }
}
end
def serial(runs)
Benchmark.measure {
runs.times{ calc() }
}
end
def print_speed_up(s_time, p_time, message,runs)
puts “speed-up: " + message + " " +
sprintf(”%.3f",s_time) + “/” + sprintf("%.3f",p_time) + " = " +
sprintf("%.3f",s_time/p_time)
puts “efficiency: " + sprintf(”%.3f",(s_time/p_time)/runs*100) + “%”
end
1.upto(MAX_RUNS) do |runs|
puts “#{runs} runs:”
serial_time = serial(runs).real
parallel_time = parallel(runs).real
parallel_p_time = parallel_proc(runs).real
print_speed_up(serial_time, parallel_time, “threads”,runs)
print_speed_up(serial_time, parallel_p_time, “procs”,runs)
end[/code]
Wyniki zaś były następujące - Ruby 1.9.0 (z paczek Debiana):
1 runs:
speed-up: threads 1.226/1.237 = 0.992
efficiency: 99.170%
speed-up: procs 1.226/1.241 = 0.988
efficiency: 98.838%
2 runs:
speed-up: threads 2.459/2.448 = 1.005
efficiency: 50.230%
speed-up: procs 2.459/1.241 = 1.982
efficiency: 99.079%
3 runs:
speed-up: threads 3.686/3.595 = 1.025
efficiency: 34.172%
speed-up: procs 3.686/1.241 = 2.970
efficiency: 98.994%
4 runs:
speed-up: threads 4.913/4.723 = 1.040
efficiency: 26.007%
speed-up: procs 4.913/1.283 = 3.828
efficiency: 95.706%
5 runs:
speed-up: threads 6.132/5.917 = 1.036
efficiency: 20.725%
speed-up: procs 6.132/1.927 = 3.182
efficiency: 63.647%
Ruby 1.9.1-p0 z opcją --enable-pthreads:
1 runs:
speed-up: threads 1.154/1.158 = 0.997
efficiency: 99.673%
speed-up: procs 1.154/1.156 = 0.998
efficiency: 99.849%
2 runs:
speed-up: threads 2.300/2.301 = 0.999
efficiency: 49.973%
speed-up: procs 2.300/1.153 = 1.994
efficiency: 99.696%
3 runs:
speed-up: threads 3.463/3.522 = 0.983
efficiency: 32.777%
speed-up: procs 3.463/1.155 = 2.998
efficiency: 99.934%
4 runs:
speed-up: threads 4.615/4.609 = 1.001
efficiency: 25.031%
speed-up: procs 4.615/1.182 = 3.905
efficiency: 97.625%
5 runs:
speed-up: threads 5.744/5.871 = 0.978
efficiency: 19.570%
speed-up: procs 5.744/1.787 = 3.214
efficiency: 64.277%
Ktoś ma pomysł skąd takie wyniki?