Memory allocation with Channels


#1

Hi all,

I am playing with channels and I have this example code.

# Example producer, will generate `N` element using function
# `ϕ` and push them in a channel of size `csize`
function Produce(ϕ, x₀::T, N::Int, csize::Int=20) where T
    # create closure to feed the channel with
    function f(ch::Channel)
        # preallocate a set of elements to be reused by `ϕ`
        xs = T[similar(x₀) for _ = 1:csize]
        # put elements in channel, will block as soon as `i == csize`
        for i = 1:N
            put!(ch, ϕ(xs[i % csize + 1]))
        end
        close(ch)
    end
    return Channel(f; ctype=T, csize=csize)
end

# Example consumer function. Just sum the sums of the
# stream elements.
function Consume(stream::Channel{T}) where T
    s = sum(take!(stream))
    while isopen(stream) || isready(stream)
        s += sum(take!(stream))
    end
    s
end

# example function that modifies x in place
ϕ(x) = (x .= 2.*x .+ 1; return x)

# warm up
stream = Produce(ϕ, randn(1000), 1000, 10)
Consume(stream)

# Time function for increasing number of generated 
# elements and fixed channel size = 10
# Number of allocations grows
for N = [10, 100, 1000, 10000]
    stream = Produce(ϕ, randn(1000), N, 10)
    @time Consume(stream)
end
println()

# Time function for increasing channel size
# Number of allocations decreases
for csize = [10, 100, 1000, 10000]
    stream = Produce(ϕ, randn(1000), 10000, csize)
    @time Consume(stream)
end

This produces the output

  0.000004 seconds (1 allocation: 16 bytes)
  0.000077 seconds (27 allocations: 896 bytes)
  0.000670 seconds (207 allocations: 3.688 KiB)
  0.006473 seconds (2.01 k allocations: 31.813 KiB)

  0.007672 seconds (2.01 k allocations: 31.813 KiB)
  0.006934 seconds (208 allocations: 9.484 KiB)
  0.009498 seconds (27 allocations: 16.609 KiB)
  0.005006 seconds (1 allocation: 16 bytes)

What I don’t get is the largish number of allocations done in the second set of calls when the channel
size is small compared to the number of elements produced N. Any suggestions?

Thanks!