我试图加快矩阵填充为茱莉亚(v0.6.0)动态规划的问题,我似乎无法使用获得多少额外的速度pmap
。 这涉及到这个问题,我发布将近一年前: 在朱莉娅采用并行处理填充一个矩阵 。 我能够加快与一些很大的帮助串行处理的话,现在我想从朱莉娅并行处理工具获得额外的速度。
对于串行处理的情况下,我使用的是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
原始三维对象:
v=zeros(Float64,gcc,gm,gz)
for i=1:gcc
v_iter(v[i,:,:],E_opt[i,:,:],gridpoint_m[i,:,:])
end
我知道,并行处理涉及建立时间,但是当我增加值gcc
,我仍然得到约等于处理时间串行和并行。 这似乎是一个很好的候选人进行并行处理,因为没有必要为工人之间的消息! 但我似乎无法使其有效地工作。