Parallel processing 多进程模块加载

Parallel processing 多进程模块加载,parallel-processing,multiprocessing,julia,Parallel Processing,Multiprocessing,Julia,我对朱莉娅在使用辅助进程时加载模块的行为感到困惑 我需要使用一个相当重的PyPlot模块,这需要相当长的时间来加载。该计划: using PyPlot pygui(true) println("Loaded") using PyPlot pygui(true) @everywhere println("Loaded") 在我的笔记本电脑上加载大约需要11秒: % time julia test.jl INFO: Loading help data... Loaded julia test.

我对朱莉娅在使用辅助进程时加载模块的行为感到困惑

我需要使用一个相当重的
PyPlot
模块,这需要相当长的时间来加载。该计划:

using PyPlot
pygui(true)
println("Loaded")
using PyPlot
pygui(true)
@everywhere println("Loaded")
在我的笔记本电脑上加载大约需要11秒:

% time julia test.jl 
INFO: Loading help data...
Loaded
julia test.jl  11,10s user 0,18s system 99% cpu 11,323 total
注意
信息:加载帮助数据…
行。它似乎是由PyPlot模块发出的,因为如果我省略使用PyPlot的
行,它就不会出现

但是,当我运行此程序时:

using PyPlot
pygui(true)
println("Loaded")
using PyPlot
pygui(true)
@everywhere println("Loaded")
我得到以下结果:

% time julia -p 4 test.jl 
INFO: Loading help data...
INFO: Loading help data...
INFO: Loading help data...
INFO: Loading help data...
INFO: Loading help data...
Loaded
    From worker 2:  Loaded
    From worker 5:  Loaded
    From worker 3:  Loaded
    From worker 4:  Loaded
julia -p 4 test.jl  88,94s user 1,19s system 266% cpu 33,865 total
它不仅运行了33秒(是原来的三倍!),而且似乎还将PyPlot模块加载到了每个工人身上

但我确信,为了让每个工人都能使用该模块,它必须是
@everywhere
d!事实上,这个简单的程序崩溃了:

module Example
    export x
    x = 10
end

using Example

@everywhere println("x: $x")
调用:

% julia -p 4 test2.jl
x: 10
exception on 2: exception on exception on exception on 4: 5: 3: ERROR: x not defined
 in eval at /usr/bin/../lib/julia/sys.so
ERROR: x not defined
 in eval at /usr/bin/../lib/julia/sys.so
ERROR: x not defined
 in eval at /usr/bin/../lib/julia/sys.so
ERROR: x not defined
 in eval at /usr/bin/../lib/julia/sys.so
那么,为什么即使我没有请求,
PyPlot
模块也会加载到所有工人身上呢

更有趣的是,还有一个变通方法:

using PyPlot
pygui(true)
addprocs(4)
@everywhere println("Loaded")
当我用julia test.jl运行这个程序时,我得到15秒:

% time julia test.jl     
INFO: Loading help data...
Loaded
    From worker 2:  Loaded
    From worker 4:  Loaded
    From worker 5:  Loaded
    From worker 3:  Loaded
julia test.jl  21,98s user 0,46s system 143% cpu 15,678 total
这正是我对使用
julia-p4 test.jl运行的原始版本的期望。但我不喜欢这种变通方法,因为它迫使我的程序使用
addprocs()


当Julia使用
-px
参数启动时,有没有办法将模块加载限制到主进程?

让我们使用
DummyModule.jl
进行测试:

module DummyModule

export MyType, f

type MyType
    a::Int
end

f(x) = x^2+1

println("loaded")

end
有了这个,我们可以看到实际上有3种可能性。所有这些实验都是从一个新的julia会话运行的,该会话被调用为
julia-p2

在所有进程上使用DummyModule 仅在驱动程序进程上使用DummyModule (请注意,不同消息的打印顺序不是确定的;在2:17的
异常中,
异常…
部分是由于进程2发出的错误,而
17
来自进程1的打印
f(4)
。)

仅在流程1上使用,但在工作人员之间传递数据
最后一种情况的区别在于序列化程序实际上知道如何在所有进程上处理
MyType
,从而可以安全地在工作人员之间传递数据。

更新:我改进了手册中的文档,请参阅感谢您的详细解释,但我仍然不明白为什么只在主流程中使用模块会迫使所有工作人员加载此模块。这似乎是违反直觉的,对于像
PyPlot
这样的大型模块,这会严重增加启动时间。是的,这是违反直觉和复杂的。加载模块而不将其纳入范围有很多用例吗?
@everywhere
还应与
include(“DummyModule.jl”)
一起使用,以便所有处理器都能看到该模块。
julia> using DummyModule
loaded
        From worker 3:  loaded
        From worker 2:  loaded

julia> @everywhere println(f(4))
exception on 2: 17
exception on 3: ERROR: f not defined
 in eval at /home/tim/src/julia/base/sysimg.jl:7
 in anonymous at multi.jl:1383
 in anonymous at multi.jl:819
 in run_work_thunk at multi.jl:592
 in run_work_thunk at multi.jl:601
 in anonymous at task.jl:6
ERROR: f not defined
 in eval at /home/tim/src/julia/base/sysimg.jl:7
 in anonymous at multi.jl:1383
 in anonymous at multi.jl:819
 in run_work_thunk at multi.jl:592
 in run_work_thunk at multi.jl:601
 in anonymous at task.jl:6

julia> rr = RemoteRef(2)
RemoteRef(2,1,19)

julia> put!(rr, MyType(7))
RemoteRef(2,1,19)

julia> using DummyModule

julia> fetch(rr)
MyType(7)