【问题标题】:Julia: How to execute functions in parallel?Julia:如何并行执行函数?
【发布时间】:2018-06-21 14:57:03
【问题描述】:

我想并行运行函数。这些函数循环执行多次。

coordSys = SharedArray{Bool}([true,false,true,true]);
dir = SharedArray{Int8}([1,2,3,2]);
load = SharedArray{Float64}([8,-7.5,7,-8.5]);
L = SharedArray{Float64}([400,450,600,500]);
r = SharedArray{Float64}([0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0 
                          0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0 
                          0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0 
                          0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0]);

显然,这些向量会很大,但为简单起见,我只放了这个有限的大小。

没有并行计算的操作:

function unifLoad(coordSys,dir,load,L,ri)
    if coordSys == true
        if dir == 1
            Q = [load;0;0];
        elseif dir == 2
            Q = [0;load;0];
        elseif dir == 3
            Q = [0;0;load];
        end
        q = ri*Q; #matrix multiplication
        P = q[1]*L/2;
        V = q[2]*L/2;
        M = -q[3]*L*L/12;
        f = [P;V;M];
    else
        f = [1.0;1.0;1.0];
    end
    return f
end

运行循环:

var = zeros(12)
for i = 1:length(L)
    var[3*(i-1)+1:3*i] = unifLoad(coordSys[i],dir[i],load[i],L[i],r[3*(i-1)+1:3*i,:]);
end

返回值为:

var
12-element Array{Float64,1}:
    0.0      
    0.0      
   -1.06667e5
    1.0      
    1.0      
    1.0      
 2100.0      
    0.0      
   -0.0      
    0.0      
 2125.0      
   -0.0

并行计算操作

我一直在尝试并行实现相同的功能,但没有得到相同的结果。

# addprocs(3)

@everywhere function unifLoad_Parallel(coordSys,dir,load,L,ri)
    if coordSys == true
        if dir == 1
            Q = [load;0;0];
        elseif dir == 2
            Q = [0;load;0];
        elseif dir == 3
            Q = [0;0;load];
        end
        q = ri*Q; # Matrix multiplication (ri -> Array 3x3)
        P = q[1]*L/2;
        V = q[2]*L/2;
        M = -q[3]*L*L/12;
        f = [P;V;M];
    else
        f = [1.0;1.0;1.0];
    end
    return f
end 

运行并行循环:

var_parallel = SharedArray{Float64}(12);

@parallel for i = 1:length(L)
        var_parallel[3*(i-1)+1:3*i] = unifLoad_Parallel(coordSys[i],dir[i],load[i],L[i],r[3*(i-1)+1:3*i,:]);
end

返回值为:

var_parallel
12-element SharedArray{Float64,1}:
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0

【问题讨论】:

  • 我得到一个边界错误:ERROR: On worker 2: BoundsError: attempt to access 0-element Array{Bool,1} at index [1] 如果我使用:@sync @parallel for ... end 以等待计算完成。

标签: parallel-processing julia


【解决方案1】:

在我的 Julia 0.6.3 上,并行代码返回相同的结果,因此我无法重现该问题(我也没有遇到 @SalchiPapa 报告的问题)。

但是,我想指出,这段代码实际上应该使用线程更快地工作(我假设真正的问题要大得多)。这是您可以使用的代码(我使用了与您等效的实现,它有点短 - 但唯一显着相关的变化是我将它包装在一个提供显着性能提升的函数中)。除了var 之外的所有数组都是共享但只能读取的关键问题。并且var 被写入,但在每个条目中只写入一次,并且不会被读取。在这种情况下,使用开销较低的线程是安全的。

这是一个示例代码(您必须在启动 Julia 之前定义 JULIA_NUM_TREADS 环境变量并将其设置为您想要的线程数 - 很可能 4 是您想要的):

using Base.Threads

function experiment()
    coordSys = [true,false,true,true];
    dir = [1,2,3,2];
    load = [8,-7.5,7,-8.5];
    L = [400,450,600,500];
    r = [0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0 
         0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0 
         0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0 
         0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0];

    unifLoad(coordSys,dir,load,L,r, i) =
        coordSys ? load * L * r[3*(i-1)+1:3*i, dir] .* [0.5, 0.5, -L/12] : [1.0, 1.0, 1.0]

    var = zeros(12)
    @threads for i = 1:length(L)
        var[3*(i-1)+1:3*i] = unifLoad(coordSys[i],dir[i],load[i],L[i],r,i);
    end
    var
end

这里还有一些使用类似想法的并行处理的简化代码:

coordSys = SharedArray{Bool}([true,false,true,true]);
dir = SharedArray{Int8}([1,2,3,2]);
load = SharedArray{Float64}([8,-7.5,7,-8.5]);
L = SharedArray{Float64}([400,450,600,500]);
r = SharedArray{Float64}([0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0 
                          0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0 
                          0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0 
                          0.0 0.0 1.0; 0.0 -1.0 0.0; 1.0 0.0 0.0]);

@everywhere unifLoad(coordSys,dir,load,L,r,i) =
        coordSys ? load * L * r[3*(i-1)+1:3*i, dir] .* [0.5, 0.5, -L/12] : [1.0, 1.0, 1.0]

vcat(pmap(i -> unifLoad(coordSys[i],dir[i],load[i],L[i],r,i), 1:length(L))...)

这里pmap主要用于简化代码,这样就不需要@sync了。

【讨论】:

    猜你喜欢
    • 2014-03-11
    • 1970-01-01
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多