平行随机数 julia

Parallel random numbers julia

考虑生成 N 随机数并将它们保存在数组中的基本迭代(假设我们对数组理解不感兴趣,也不知道调用 rand(N) )

function random_numbers(N::Int)
array = zeros(N)
for i in 1:N
    array[i] = rand()
end
array
end

我对利用笔记本电脑内核生成相同数组的类似函数很感兴趣。我已经检查了 this nice blog 引入宏 @everywhere@spawn@parallel 的地方,但是在那里进行了计算 "on-the-fly" 并且不需要数组来保存数据。

我的印象是这是非常基本的,可以使用函数 pmap 轻松完成,但我不熟悉并行计算。

我的目标是将此方法应用于我构建的函数,以生成从异常分布中抽取的随机数。

正如评论中所建议的,始终欢迎对问题进行更多说明。但是,似乎 pmap 会执行所需的操作。相关文档是here.

下面是一个例子。请注意,pmap 方法花费的时间是常规 map 方法的一半。如果是 16 核,情况可能会好很多:

julia> addprocs(2)
2-element Array{Int64,1}:
 2
 3

julia> @everywhere long_rand() = foldl(+,0,(randn() for i=1:10_000_000))

julia> long_rand()
-1165.9596619177153

julia> @time map(x->long_rand(), zeros(10,10))
  8.455930 seconds (204.89 k allocations: 11.069 MiB)
10×10 Array{Float64,2}:
   ⋮
   ⋮ 

julia> @time pmap(x->long_rand(), zeros(10,10));
  6.125479 seconds (773.08 k allocations: 42.242 MiB, 0.25% gc time)

julia> @time pmap(x->long_rand(), zeros(10,10))
  4.609745 seconds (20.99 k allocations: 954.991 KiB)
10×10 Array{Float64,2}:
   ⋮
   ⋮ 

我建议在并行进程中更仔细地初始化随机数生成器,例如:

# choose the seed you want
@everywhere srand(1)
# replace 10 below by maximum process id in your case
@everywhere const LOCAL_R = randjump(Base.GLOBAL_RNG, 10)[myid()]
# here is an example usage
@everywhere f() = rand(LOCAL_R)

这样你:

  • 确保您的结果可重现;
  • 控制不同进程生成的随机序列之间没有重叠。