Skip to content

Instantly share code, notes, and snippets.

@seki
Last active August 16, 2017 01:42
Show Gist options
  • Save seki/6829d0f30e862cafeb9cfed4082957f8 to your computer and use it in GitHub Desktop.
Save seki/6829d0f30e862cafeb9cfed4082957f8 to your computer and use it in GitHub Desktop.
Rinda sample for Nagoya RubyKaigi
require 'drb'
require 'rinda/tuplespace'
module Rinda
module_function
def rinda_eval(ts)
ts = DRbObject.new(ts) unless DRbObject === ts
pid = fork do
Thread.current['DRb'] = nil
DRb.stop_service
tuple = yield(ts)
ts.write(tuple) rescue nil
end
Process.detach(pid)
end
end
require 'matrix'
N = 10
$data = Hash.new {|h, k| h[k] = Vector.elements((0..200000).collect {rand})}
$target = $data[:target]
N.times do |y|
N.times do |x|
$data[[x, y]]
end
end
Entry = Struct.new(:x, :y, :score)
def make_entry(x, y)
Entry.new(x, y, $data[[x, y]].dot($target))
end
max = root = make_entry(0, 0)
srand(0)
DRb.start_service
require 'benchmark'
Benchmark.bm 10 do |r|
max = make_entry(0, 0)
r.report "basic" do
N.times do |y|
N.times do |x|
entry = make_entry(x, y)
max = max.score < entry.score ? entry : max
end
end
end
p max
r.report "wave front" do
ts = Rinda::TupleSpace.new
N.times do |y|
N.times do |x|
Rinda::rinda_eval(ts) do |place|
entry = make_entry(x, y)
if x > 0
left = place.read([x-1, y, nil])[2]
entry = left.score < entry.score ? entry : left
end
if y > 0
top = place.read([x, y-1, nil])[2]
entry = top.score < entry.score ? entry : top
end
[x, y, entry]
end
end
end
max = ts.take([N-1,N-1,nil])[2]
end
p max
r.report "line" do
ts = Rinda::TupleSpace.new
N.times do |y|
Rinda::rinda_eval(ts) do |place|
max = make_entry(0, y)
(1...N).each do |x|
entry = make_entry(x, y)
max = max.score < entry.score ? entry : max
end
if y > 0
entry = place.read([y-1, nil])[1]
max = max.score < entry.score ? entry : max
end
[y, max]
end
end
max = ts.take([N-1,nil])[1]
end
p max
r.report "worker" do
ts = Rinda::TupleSpace.new
4.times do
Rinda::rinda_eval(ts) do |place|
while true
_, w, h = place.take(['task', nil, nil])
break unless w
max = make_entry(0, 0)
w.each do |y|
h.each do |x|
entry = make_entry(x, y)
max = max.score < entry.score ? entry : max
end
end
place.write(['result', max])
end
['done']
end
end
N.times do |y|
ts.write(['task', (1...N), (y..y)])
end
max = root
N.times do
entry = ts.take(['result', nil])[1]
max = max.score < entry.score ? entry : max
end
4.times do
ts.write(['task', nil, nil])
end
4.times do
ts.take(['done'])
end
end
p max
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment