On Fri, Sep 9, 2016 at 12:07 PM, Sleort <tr...@online.no> wrote:

> I've been playing around with the parallel functionality of Julia (0.4.6)
> in order to get a better understanding of it. Just for the sake of testing,
> I made a "silly" nworkers() implementation like
> julia> function silly_nworkers()
>   @parallel (+) for p in workers()
>     1
>   end
> end
> which, as expected, return the number of workers - just like nworkers().
> Now, running julia -p 2 (or any other number of processes)
> julia> @code_warntype silly_nworkers()
> I get the result
> Variables:
>
>
> Body:
>   begin  # none, line 2:
>       return (AST(:($(Expr(:lambda, Any[], Any[Any[Any[symbol("#8#
> therange"),Array{Int64,1},19]],Any[],Any[Function],Any[]], :(begin  #
> expr.jl, line 113:
>         NewvarNode(symbol("#8#therange")) # multi.jl, line 1587:
>         #8#therange = (Main.workers)()::Array{Int64,1} # multi.jl, line
> 1587: # multi.jl, line 1542:
>         GenSym(0) = AST(:($(Expr(:lambda, Any[:(#9#lo::(top(getfield))(
> Base,:Int)::Any::Any),:(#10#hi::(top(getfield))(Base,:Int)::Any::Any)],
> Any[Any[Any[symbol("#9#lo"),Any,18],Any[symbol("#10#hi"),
> Any,18],Any[:p,Any,2],Any[symbol("#11#ac"),Any,2],Any[
> symbol("#s7"),Any,2]],Any[Any[symbol("#8#therange"),Array{Int64,1},19]],4,Any[]],
> :(begin
>         #9#lo = (top(typeassert))(#9#lo,(top(getfield))(Base,:Int)::Any)::
> Any
>         #10#hi = (top(typeassert))(#10#hi,(top(
> getfield))(Base,:Int)::Any)::Any # multi.jl, line 1543:
>         p = (Main.getindex)(#8#therange,#9#lo)::Any # multi.jl, line
> 1544: # none, line 3:
>         #11#ac = 1 # multi.jl, line 1545:
>         unless ((top(getfield))(Base,:(!=))::Any)(#9#lo,#10#hi)::Any goto
> 0 # multi.jl, line 1546:
>         GenSym(1) = (Main.getindex)(#8#therange,(
> Main.colon)(((top(getfield))(Base,:+)::Any)(#9#lo,1)::Any,#
> 10#hi)::Any)::Any
>         #s7 = (top(start))(GenSym(1))::Any
>         unless (top(!))((top(done))(GenSym(1),#s7)::Any)::Any goto 1
>         2:
>         GenSym(2) = (top(next))(GenSym(1),#s7)::Any
>         p = (top(getfield))(GenSym(2),1)::Any
>         #s7 = (top(getfield))(GenSym(2),2)::Any # multi.jl, line 1547: #
> none, line 3:
>         GenSym(3) = 1
>         #11#ac = #11#ac + GenSym(3)::Any
>         3:
>         unless (top(!))((top(!))((top(done))(GenSym(1),#s7)::Any)::Any)::Any
> goto 2
>         1:
>         0:  # multi.jl, line 1550:
>         return #11#ac
>     end::Any)))))
>         return ((top(getfield))(Base,:preduce)::F)(Main.+,GenSym(0),(Base.
> arraylen)(#8#therange::Array{Int64,1})::Int64)::Any
>     end::Any))))))()::Any
>   end::Any
> where there is a large number of undetermined types/Anys in the code.
> (Except for that, I must admit that I don't understand all the details of
> the code/output itself). The conventional Julia optimization wisdom tells
> me that I should have specific types in order to get fast code. What's
> going on here, and is there a way to "fix"/improve this situation? The
> silly_nworkers() itself seems to be rather straightforward to me, so I'm
> not sure why the compiler cannot make more type-specific code...
>

The inter process communication has a lot of overhead which means,

1. You should put more work in the loop body, otherwise it's not going to
speed things up.
2. The type instability of the multi processing infrastructure doesn't
really matter compare to the communication overhead.

Reply via email to