Arrays 结合两个sharedarray的基本操作
我花了大约一个月的时间学习朱莉娅,我印象深刻。特别是我在分析大量的气候模型输出,我将所有这些都放入Arrays 结合两个sharedarray的基本操作,arrays,function,parallel-processing,julia,Arrays,Function,Parallel Processing,Julia,我花了大约一个月的时间学习朱莉娅,我印象深刻。特别是我在分析大量的气候模型输出,我将所有这些都放入SharedArrays中,并对其进行平行调整和绘制。到目前为止,它非常快速和高效,我有相当多的代码库。我当前的问题是创建一个可以在两个共享阵列上执行基本操作的函数。我已经成功地编写了一个函数,该函数包含两个数组以及您希望如何处理它们。代码基于julia文档并行部分中的示例,并使用myrange函数,如图所示 function myrange(q::SharedArray) idx = in
SharedArrays
中,并对其进行平行调整和绘制。到目前为止,它非常快速和高效,我有相当多的代码库。我当前的问题是创建一个可以在两个共享阵列上执行基本操作的函数。我已经成功地编写了一个函数,该函数包含两个数组以及您希望如何处理它们。代码基于julia文档并行部分中的示例,并使用myrange
函数,如图所示
function myrange(q::SharedArray)
idx = indexpids(q)
#@show (idx)
if idx == 0
# This worker is not assigned a piece
return 1:0, 1:0
print("NO WORKERS ASSIGNED")
end
nchunks = length(procs(q))
splits = [round(Int, s) for s in linspace(0,length(q),nchunks+1)]
splits[idx]+1:splits[idx+1]
end
function combine_arrays_chunk!(array_1,array_2,output_array,func, length_range);
#@show (length_range)
for i in length_range
output_array[i] = func(array_1[i], array_2[i]);
#hardwired example for func = +
#output_array[i] = +(array_1[i], array_2[i]);
end
output_array
end
combine_arrays_shared_chunk!(array_1,array_2,output_array,func) = combine_arrays_chunk!(array_1,array_2,output_array,func, myrange(array_1));
function combine_arrays_shared(array_1::SharedArray,array_2::SharedArray,func)
if size(array_1)!=size(array_2)
return print("inputs not of the same size")
end
output_array=SharedArray(Float64,size(array_1));
@sync begin
for p in procs(array_1)
@async remotecall_wait(p, combine_arrays_shared_chunk!, array_1,array_2,output_array,func)
end
end
output_array
end
这是一个人所能做的工作
strain_div = combine_arrays_shared(eps_1,eps_2,+);
strain_tot = combine_arrays_shared(eps_1,eps_2,hypot);
如果结果正确,则会根据需要将输出作为共享数组。但是相当慢。将sharedarray
组合为一个处理器上的普通阵列,计算并转换回sharedarray
(对于我的测试用例,每个阵列大约200MB,当我移动到GBs时,我想不会)。我可以硬连接combined\u arrays\u shared
函数,只做加法(或其他一些函数),然后速度会提高,但如果在combined\u arrays\u shared
中传递函数类型,整个过程会变慢(比硬连接加法慢10倍)
我已经看过了FastAnonymous.jl
包,但是我看不出它在这种情况下是如何工作的。我试过了,但失败了。有什么想法吗
我可能会为我使用的每个基本函数编写一个不同的combine\u arrays\u…
函数,或者将func
参数作为一个选项,从combine\u arrays\u shared
中调用不同的函数,但我希望它更加优雅!这也是了解朱莉娅的好方法
Harry这个问题实际上与ShareDarray无关,只是“如何将函数作为参数传递并获得更好的性能?” FastAnonymous的工作方式——类似于julia soon中闭包的工作方式——是使用
调用方法创建一个类型。如果由于某种原因,您在使用FastAnonymous时遇到问题,您始终可以手动执行:
julia> immutable Foo end
julia> Base.call(f::Foo, x, y) = x*y
call (generic function with 1036 methods)
julia> function applyf(f, X)
s = zero(eltype(X))
for x in X
s += f(x, x)
end
s
end
applyf (generic function with 1 method)
julia> X = rand(10^6);
julia> f = Foo()
Foo()
# Run the function once with each type of argument to JIT-compile
julia> applyf(f, X)
333375.63216645207
julia> applyf(*, X)
333375.63216645207
# Compile anything used by @time
julia> @time 1
0.000004 seconds (148 allocations: 10.151 KB)
1
# Now let's benchmark
julia> @time applyf(f, X)
0.002860 seconds (5 allocations: 176 bytes)
333433.439233112
julia> @time applyf(*, X)
0.142411 seconds (4.00 M allocations: 61.035 MB, 19.24% gc time)
333433.439233112
请注意速度的大幅提高和内存消耗的大幅减少。这是一个正确回答问题的例子!现在这更有意义了,因此我可以将类型f分配给我需要的函数,然后有效地传递函数。有没有办法在函数中指定此类型?因此,在我上面的例子中,顶部的combine\u arrays\u shared
将进行赋值,然后函数将高效地传递给combine\u arrays\u块代码>功能?我要试一试。