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块功能?我要试一试。