Skip to content

Instantly share code, notes, and snippets.

@ugovaretto
Last active Sep 23, 2020
Embed
What would you like to do?
Parallel update of elements in large arrays in Crystal
# Author: Ugo Varetto
# Fiber test: parallel update of array elements in arrays larger than 2^32
# build with 'crystal build -Dpreview_mt --release hello_fibers.cr'
require "process"
unless ARGV.size > 0
p "#{PROGRAM_NAME} <size> <num threads> <channel buffer size>"
exit 1
end
puts "Process id: #{Process.pid}" #use with 'top -H -p <pid>'
size = ARGV[0].to_u64?(underscore:true) || 100000.to_u64
#can allocate arrays of any size > 2^32, garbage collected
data = Pointer(UInt64).malloc(size)
(0.to_u64...size).each do |i|
data[i] = i
end
def update(data, startIdx : UInt64, span : UInt64, doneCh)
(startIdx...(startIdx+span)).each do |j|
data[j] += 10
end
doneCh.send nil #notify of completion
end
numFibers = ARGV[1].to_u16? || 10
notificationBufferSize = ARGV[2].to_u16? || 1
arraySpan = size // numFibers
doneCh = Channel(Nil).new(notificationBufferSize.to_i32)
elapsed_time = Time.measure do
(0...numFibers).each do |i|
spawn update data, arraySpan*i, arraySpan, doneCh
end
numFibers.times do
doneCh.receive
end
end
p "# elements: #{size.to_f64}, # threads: #{numFibers}, " \
"buffer size: #{notificationBufferSize}"
p "Elapsed time: #{elapsed_time.milliseconds} ms"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment