Trying to understand where all the memory allocations in a call to "notify" are coming from.

140 views
Skip to first unread message

Amit Murthy

unread,
Jul 4, 2015, 9:23:52 AM7/4/15
to juli...@googlegroups.com
Consider the following code:

julia> function foo()
           c
=Condition()
           
for i in 1:10^6
               notify
(c)
           
end
       
end
foo
(generic function with 1 method)
 
julia
> foo()
 
julia
> @time foo()
 
158.151 milliseconds (2000 k allocations: 122 MB, 4.75% gc time)


That is a lot of memory allocations.


`notify` in task.jl is defined as 

function notify(c::Condition, arg::ANY=nothing; all=true, error=false)
   
if all
       
for t in c.waitq
            schedule
(t, arg, error=error)
       
end
        empty
!(c.waitq)
    elseif
!isempty(c.waitq)
        t
= shift!(c.waitq)
        schedule
(t, arg, error=error)
   
end
    nothing
end



and in this case c.waitq is always empty.

If I specify a keyword arg, for example, `notify(c; all=false)`, number of mem allocations goes up 4 times.



julia
> function foo()
           c
=Condition()
           
for i in 1:10^6
               notify
(c; all=false)
           
end
       
end
foo
(generic function with 1 method)
 
julia
> foo()
 
julia
> @time foo()
   
2.445 seconds      (8000 k allocations: 381 MB, 2.73% gc time)



Considering the `notify` call:

julia> const ct=Condition()
Condition(Any[])

julia
> @code_typed notify(ct)
1-element Array{Any,1}:
 
:($(Expr(:lambda, Any[:c], Any[Any[Any[:c,Condition,0]],Any[],Any[Union{},Union{},Union{},Union{},Union{},Union{},Union{},Union{},Array{Any,1},Array{Any,1},Int64],Any[]], :(begin $(Exp
r
(:line, 236, symbol("task.jl"), symbol("")))
       
GenSym(8) = (top(ccall))(:jl_alloc_array_1d,(top(apply_type))(Array,Any,1)::Type{Array{Any,1}},(top(svec))(Any,Int)::SimpleVector,Array{Any,1},0,0,0)::Array{Any,1}
       
GenSym(9) = GenSym(8)
       
return __notify#26__(GenSym(9),c::Condition)::Void
   
end::Void))))



Why is there a `ccall` and `jl_alloc_array_1d`? Is this due to pre-compilation?  What exactly is happening here?


Yichao Yu

unread,
Jul 4, 2015, 9:59:47 AM7/4/15
to Julia Dev
These are coming from the packing of keyword arguments and is exactly
why they are very slow.

>
>

Amit Murthy

unread,
Jul 4, 2015, 12:15:23 PM7/4/15
to juli...@googlegroups.com
OK. Also noticed that,

function bar(x;a=1, b=2)
    x+a+b
end

is OK when invoked as bar(1), but slow when invoked as bar(1; a=1)

but

function bar(x, y=1; a=1, b=2)
    x+a+b
end

is slow even when invoked as bar(1)

Yichao Yu

unread,
Jul 4, 2015, 1:04:45 PM7/4/15
to Julia Dev
On Sat, Jul 4, 2015 at 12:15 PM, Amit Murthy <amit....@gmail.com> wrote:
> OK. Also noticed that,
>
> function bar(x;a=1, b=2)
> x+a+b
> end
>
> is OK when invoked as bar(1), but slow when invoked as bar(1; a=1)
>
> but
>
> function bar(x, y=1; a=1, b=2)
> x+a+b
> end
>
> is slow even when invoked as bar(1)

It's fast if invoked as bar(1, 1). This one can probably be fixed
without too much effort.

Andreas Noack

unread,
Jul 6, 2015, 10:36:46 AM7/6/15
to juli...@googlegroups.com
Maybe this should be filed as an issue such that we don't lose track of it.
Reply all
Reply to author
Forward
0 new messages