我正在尝试加快填充 Julia(v0.6.0)中动态编程问题的矩阵,但我似乎无法从使用pmap
. 这与我差不多一年前发布的这个问题有关:Filling a matrix using parallel processing in Julia。那时我能够在一些很大的帮助下加速串行处理,现在我正试图从 Julia 的并行处理工具中获得额外的速度。
对于串行处理案例,我使用了一个 3 维矩阵(本质上是一组大小相等的矩阵,由第一维索引)并在第一维上进行迭代。不过,我想pmap
尝试一下,以更有效地迭代矩阵集。
这是代码设置。为了使用下面pmap
的v_iter
函数,我将三维矩阵转换为字典对象,字典键等于第一维中的索引值(v_dict
在下面的代码中,gcc
等于第一维大小)。该v_iter
函数将其他字典对象(E_opt_dict
及gridpoint_m_dict
以下)作为附加输入:
function v_iter(a,b,c)
diff_v = 1
while diff_v>convcrit
diff_v = -Inf
#These lines efficiently multiply the value function by the Markov transition matrix, using the A_mul_B function
exp_v = zeros(Float64,gkpc,1)
A_mul_B!(exp_v,a[1:gkpc,:],Zprob[1,:])
for j=2:gz
temp=Array{Float64}(gkpc,1)
A_mul_B!(temp,a[(j-1)*gkpc+1:(j-1)*gkpc+gkpc,:],Zprob[j,:])
exp_v=hcat(exp_v,temp)
end
#This tries to find the optimal value of v
for h=1:gm
for j=1:gz
oldv = a[h,j]
newv = (1-tau)*b[h,j]+beta*exp_v[c[h,j],j]
a[h,j] = newv
diff_v = max(diff_v, oldv-newv, newv-oldv)
end
end
end
end
gz = 9
gp = 13
gk = 17
gcc = 5
gm = gk * gp * gcc * gz
gkpc = gk * gp * gcc
gkp = gk*gp
beta = ((1+0.015)^(-1))
tau = 0.35
Zprob = [0.43 0.38 0.15 0.03 0.00 0.00 0.00 0.00 0.00; 0.05 0.47 0.35 0.11 0.02 0.00 0.00 0.00 0.00; 0.01 0.10 0.50 0.30 0.08 0.01 0.00 0.00 0.00; 0.00 0.02 0.15 0.51 0.26 0.06 0.01 0.00 0.00; 0.00 0.00 0.03 0.21 0.52 0.21 0.03 0.00 0.00 ; 0.00 0.00 0.01 0.06 0.26 0.51 0.15 0.02 0.00 ; 0.00 0.00 0.00 0.01 0.08 0.30 0.50 0.10 0.01 ; 0.00 0.00 0.00 0.00 0.02 0.11 0.35 0.47 0.05; 0.00 0.00 0.00 0.00 0.00 0.03 0.15 0.38 0.43]
convcrit = 0.001 # chosen convergence criterion
E_opt = Array{Float64}(gcc,gm,gz)
fill!(E_opt,10.0)
gridpoint_m = Array{Int64}(gcc,gm,gz)
fill!(gridpoint_m,fld(gkp,2))
v_dict=Dict(i => zeros(Float64,gm,gz) for i=1:gcc)
E_opt_dict=Dict(i => E_opt[i,:,:] for i=1:gcc)
gridpoint_m_dict=Dict(i => gridpoint_m[i,:,:] for i=1:gcc)
对于并行处理,我执行了以下两个命令:
wp = CachingPool(workers())
addprocs(3)
pmap(wp,v_iter,values(v_dict),values(E_opt_dict),values(gridpoint_m_dict))
...产生了这种表现:
135.626417 seconds (3.29 G allocations: 57.152 GiB, 3.74% gc time)
然后我尝试改为串行处理:
for i=1:gcc
v_iter(v_dict[i],E_opt_dict[i],gridpoint_m_dict[i])
end
...并获得了更好的表现。
128.263852 seconds (3.29 G allocations: 57.101 GiB, 4.53% gc time)
v_iter
这也给了我与在原始 3 维对象上运行相同的性能:
v=zeros(Float64,gcc,gm,gz)
for i=1:gcc
v_iter(v[i,:,:],E_opt[i,:,:],gridpoint_m[i,:,:])
end
我知道并行处理涉及设置时间,但是当我增加 的值gcc
时,串行和并行的处理时间仍然大致相同。这似乎是并行处理的一个很好的候选,因为不需要在工作人员之间进行消息传递!但我似乎无法让它有效地工作。