我试图了解SharedArray类型的数据是否在进程间移动,从而导致开销。
在我的Main模块(过程1)中定义了变量之后,我在数据的Array( im1 )和SharedArray( im1_shared )版本上调用了pmap。
pmap(someFunction(im1, im2, x), iterations)
pmap(someFunction(im1_shared, im2_shared, x), iterations)
因此 im1 , im2 和 im1_shared , im2_shared 是默认参数,并且分片使用迭代器x,由工作人员处理。
使用
@fetchfrom 2 varinfo()
我得到:
im1 122.070 MiB 4000×4000阵列{Float64,2}
im2 122.070 MiB 4000×4000阵列{Float64,2}
im1_shared 122.071 MiB 4000×4000 SharedArray {Float64,2}
im2_shared 122.071 MiB 4000×4000 SharedArray {Float64,2}
所以我对此的想法和困惑:
工作程序(此处为工作程序2)也列出了SharedArrays。因此,我认为其中任何一个都可能部分正确:
2.1。 varinfo()
列出了工作程序的本地工作区中的所有变量,但SharedArrays未存储在这些变量的本地内存中。列出它们只是暗示一个工人可以访问它们。
在这种情况下,如果SharedArrays仅存储一次并且所有工作人员都可以访问它们,那么为什么这些类型在Julia中没有默认设置-首先将开销降至最低?
2.2 SharedArray也被复制到每个工作线程,因此每个SharedArray的122 MiB。因此,SharedArrays优于Arrays的唯一优势是每个工作人员的访问权限。存储的数据必须以任何一种方式复制。
在这种情况下,避免开销的唯一方法是使用分布式数组之类的方法,让工作人员仅对已经可以访问/已存储在内存中的块进行操作,对吧? < / p>
请您帮我整理一下这两种情况(2.1和2.2)。
更新1:这是一个有效的示例:
@everywhere using InteractiveUtils # to call varinfo() on all workers
### FUNCTIONS
@everywhere function foo(x::Array{Float64, 2}, y::Array{Float64, 2}, t::Int64)
#just take a slice of both arrays at dfined steps and sum the values
x_slice = x[t:t+5, t:t+5]
y_slice = y[t:t+5, t:t+5]
return x_slice + y_slice
end
@everywhere function fooShared(x::SharedArray{Float64, 2}, y::SharedArray{Float64, 2}, t::Int64)
#just take a slice of both arrays at dfined steps and sum the values
x_slice = x[t:t+5, t:t+5]
y_slice = y[t:t+5, t:t+5]
return x_slice + y_slice
end
### DATA
n = 1000
#the two Arrays
im1 = rand(1.0:2.0, n, n)
im2 = copy(im1);
#The two shared arrays
im1_shared = SharedArray(im1)
im2_shared = SharedArray(im2);
@fetchfrom 2 varinfo() # im1_shared and im2_shared are not yet listed, of course not...
pmap(x -> foo(im1, im2, x), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
pmap(x -> fooShared(im1_shared, im2_shared, x), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
@fetchfrom 2 varinfo() # im1_shared and im2_shared are now listed
答案 0 :(得分:1)
SharedArray
通过内存映射(https://docs.julialang.org/en/v1/stdlib/Mmap/index.html)在许多Julia进程之间共享。数据可以通过以下方式初始化:
using Distributed
Distributed.addprocs(2);
@everywhere using SharedArrays
@everywhere function ff(ss::SharedArray)
println(myid()," ",localindices(ss))
for ind in localindices(ss)
ss[ind] = rand(1.0:2.0)
end
end
现在让我们执行实际的初始化:
julia> s = SharedArray{Float64}((1000,1000),init=ff)
From worker 2: 2 1:500000
From worker 3: 3 500001:1000000
1000×1000 SharedArray{Float64,2}:
2.0 1.0 1.0 1.0 1.0 2.0 … 2.0 1.0 2.0 2.0 1.0
2.0 2.0 2.0 2.0 2.0 2.0 2.0 1.0 2.0 1.0 2.0
2.0 1.0 1.0 2.0 1.0 2.0 1.0 1.0 1.0 1.0 2.0
⋮ ⋮ ⋱ ⋮
1.0 1.0 1.0 1.0 1.0 2.0 2.0 2.0 1.0 1.0 1.0
1.0 2.0 1.0 2.0 2.0 1.0 2.0 2.0 1.0 1.0 1.0
2.0 2.0 1.0 2.0 1.0 2.0 2.0 1.0 1.0 2.0 2.0
您可以看到,每个工作程序都初始化了其处理的数组的单独部分。