Parallel processing 使用@everywhere在julia中传递共享数组

Parallel processing 使用@everywhere在julia中传递共享数组,parallel-processing,julia,Parallel Processing,Julia,我找到了这篇文章-,这显然很接近,但我仍然不知道在我的情况下该怎么办 我试图将共享数组传递给我定义的函数,并使用@everywhere调用该函数。没有共享阵列的以下操作有效: @everywhere mat = rand(3,3) @everywhere foo1(x::Array) = det(x) 那么这个 @everywhere println(foo1(mat)) @everywhere println(foo2(mat,test)) 正确地从每个工人那里产生不同的结果。现在让我包

我找到了这篇文章-,这显然很接近,但我仍然不知道在我的情况下该怎么办

我试图将共享数组传递给我定义的函数,并使用@everywhere调用该函数。没有共享阵列的以下操作有效:

@everywhere mat = rand(3,3)
@everywhere foo1(x::Array) = det(x)
那么这个

@everywhere println(foo1(mat))
@everywhere println(foo2(mat,test))
正确地从每个工人那里产生不同的结果。现在让我包括一个共享阵列:

test = SharedArray(Float64,10)
@everywhere foo2(x::Array,y::SharedArray) = det(x) + sum(y)
那么这个

@everywhere println(foo1(mat))
@everywhere println(foo2(mat,test))
对工人们来说失败了

ERROR: On worker 2:
UndefVarError: test not defined
等等。我可以像这样得到我想要的:

  for w in procs()
         @spawnat w println(foo2(eval(:mat),test))
   end
mat = [@spawnat p rand(3,3) for p in workers()] # process 1 holds references to objects on workers
@sync for (i, p) in enumerate(workers())
    @spawnat p foo(mat[i], sharedarray)
end

这是可行的,但它是最优的吗?有没有办法让它与@everywhere一起工作

虽然在worker上使用“命名变量”很有诱惑力,但如果您通过引用访问它们,通常效果会更好。示意图上,您可以执行以下操作:

  for w in procs()
         @spawnat w println(foo2(eval(:mat),test))
   end
mat = [@spawnat p rand(3,3) for p in workers()] # process 1 holds references to objects on workers
@sync for (i, p) in enumerate(workers())
    @spawnat p foo(mat[i], sharedarray)
end

您是否尝试过@everywhere test=…?您是否可以发布一个可复制的示例,说明您在使用
@spawn
时遇到了性能问题?我看不出你在最后使用
@spawn
发布的示例有任何错误,也看不出它有任何性能问题。在玩这个东西的过程中,我开始相信,@aireties,性能问题与使用无关,也不是无处不在。我想在进行比较时,我混合了一些其他的代码差异。因此,我为这篇不健康的帖子道歉。不确定现在应该采取什么正确的行动-删除帖子?我认为你不需要删除帖子,只需编辑一下即可。您报告得到的最初错误是我认为其他用户可能会遇到的错误,@tholy的回答对此很有用。我会删除帖子中对减速的引用,并留下关于错误消息的信息。事实上,我认为这是你最初提出的一个很好的问题。此外,使用
@everywhere
启动处理器密集型作业通常是次优的。你不希望你的主控制器处理器做繁重的工作,而这正是
@everywhere
宏在没有大量笨拙代码的情况下可以避免的。Thoy说,这看起来确实是更好的形式。然而,它似乎不太适合我。如果我这样做,mat[I]是一个远程引用,当通过spawnat传递时,它仍然是一个远程引用。因此,如果foo的第一个参数应该是一个数组(我尝试过!),那么我实际上会在工作进程上生成一个错误。我可以用fetch(mat[I])替换mat[I]来修复它。但这是否真的会将mat[i]的值拉回到进程1,然后将其发送到进程p?由于在手机上,我无法测试它。在你的函数中,你应该能够向你正在运行的函数中添加一个
fetch
。@LeonBalents我不认为像你描述的那样,spawn与fetch相结合应该做到这一点。Spawn表示该命令在工作进程上运行。但我还没有尝试明确地测试它