What’s a good pattern for preallocating buffers in a multithreaded setting? I want to avoid allocating new memory whenever I launch a task on a thread.
So far I’ve been using the following pattern, which maintains a pool of ids which are used to index into a collection of buffers. In retrospect, this would also work for an asynchronous (rather than multithreaded) setting, with t
being the maximum number of tasks running at a time. Below, the goal is to compute some function f(x, buffer) that relies on a preallocated buffer.
t = Threads.nthreads()
# local buffers
buffers = [zeros(UInt8, 10^6) for _ in 1:t]
# queue of ids
available_ids = Channel{Int}(t)
for i in 1:t
put!(available_ids, i)
end
@sync for x in data
# grab an id from the queue
# this doesn't need to match the value returned by Threads.threadid()
id = take!(available_ids)
Threads.@spawn begin
# get local buffer
buffer = buffers[id]
# compute some complicated function f(x, buffer)
# that uses a preallocated buffer
# ...
# return id to queue
put!(available_ids, id)
end
end
Is there a better or more standard way of doing this?