Parallel processing Julia-@按顺序而不是并行生成计算作业

Parallel processing Julia-@按顺序而不是并行生成计算作业,parallel-processing,julia,multicore,Parallel Processing,Julia,Multicore,我试图使用@spawn宏在Julia(1.1.0版)中并行运行一个函数 我注意到使用@spawn作业实际上是按顺序执行的(尽管来自不同的工作人员)。 当使用[pmap][1]函数并行计算作业时,不会发生这种情况 以下是调用应执行的函数(在模块hello\u模块中)的main.jl程序的代码: #### MAIN START #### # deploy the workers addprocs(4) # load modules with multi-core functions @everywh

我试图使用
@spawn
宏在Julia(1.1.0版)中并行运行一个函数

我注意到使用
@spawn
作业实际上是按顺序执行的(尽管来自不同的工作人员)。 当使用[pmap][1]函数并行计算作业时,不会发生这种情况

以下是调用应执行的函数(在模块
hello\u模块中)的
main.jl
程序的代码:

#### MAIN START ####
# deploy the workers
addprocs(4)
# load modules with multi-core functions
@everywhere include(joinpath(dirname(@__FILE__), "hello_module.jl"))

# number of cores
cpus = nworkers()

# print hello world in parallel
hello_module.parallel_hello_world(cpus)

  [1]: https://docs.julialang.org/en/v1/stdlib/Distributed/#Distributed.pmap
…下面是模块的代码:

module hello_module    
using Distributed
using Printf: @printf
using Base

"""Print Hello World on STDOUT"""
function hello_world()
    println("Hello World!")
end

"""Print Hello World in Parallel."""
function parallel_hello_world(threads::Int)

    # create array with as many elements as the threads
    a = [x for x=1:threads]

    #= This would perform the computation in parallel
    wp = WorkerPool(workers())
    c = pmap(hello_world, wp, a, distributed=true)
    =#

    # spawn the jobs
    for t in a
        r = @spawn hello_world()
        # @show r
        s = fetch(r)
    end    
end

end # module end

您需要使用绿色线程来管理并行性。 在Julia中,它是通过使用
@sync
@async
宏来实现的。 请参见下面的最小工作示例:

using Distributed

addprocs(3)
@everywhere using Dates
@everywhere function f()
    println("starting at $(myid()) time $(now()) ")
    sleep(1)
    println("finishing at $(myid()) time $(now()) ")
    return myid()^3
end

function test()
    fs = Dict{Int,Future}()
    @sync for w in workers()
        @async fs[w] = @spawnat w f()
    end
    res = Dict{Int,Int}()
    @sync for w in workers()
        @async res[w] = fetch(fs[w])
    end
    res
end
这里的输出清楚地显示了这些功能正在并行运行:

julia> test()
      From worker 3:    starting at 3 time 2019-04-02T01:18:48.411
      From worker 2:    starting at 2 time 2019-04-02T01:18:48.411
      From worker 4:    starting at 4 time 2019-04-02T01:18:48.415
      From worker 2:    finishing at 2 time 2019-04-02T01:18:49.414
      From worker 3:    finishing at 3 time 2019-04-02T01:18:49.414
      From worker 4:    finishing at 4 time 2019-04-02T01:18:49.418
Dict{Int64,Int64} with 3 entries:
  4 => 64
  2 => 8
  3 => 27
编辑:

我建议您管理计算的分配方式。但是,您也可以使用
@spawn
。请注意,在下面的场景中,工作会同时分配给工人

function test(N::Int)
    fs = Dict{Int,Future}()
    @sync for task in 1:N
        @async fs[task] = @spawn f()
    end
    res = Dict{Int,Int}()
    @sync for task in 1:N
        @async res[task] = fetch(fs[task])
    end
    res
end
以下是输出:

julia> test(6)
      From worker 2:    starting at 2 time 2019-04-02T10:03:07.332
      From worker 2:    starting at 2 time 2019-04-02T10:03:07.34
      From worker 3:    starting at 3 time 2019-04-02T10:03:07.332
      From worker 3:    starting at 3 time 2019-04-02T10:03:07.34
      From worker 4:    starting at 4 time 2019-04-02T10:03:07.332
      From worker 4:    starting at 4 time 2019-04-02T10:03:07.34
      From worker 4:    finishin at 4 time 2019-04-02T10:03:08.348
      From worker 2:    finishin at 2 time 2019-04-02T10:03:08.348
      From worker 3:    finishin at 3 time 2019-04-02T10:03:08.348
      From worker 3:    finishin at 3 time 2019-04-02T10:03:08.348
      From worker 4:    finishin at 4 time 2019-04-02T10:03:08.348
      From worker 2:    finishin at 2 time 2019-04-02T10:03:08.348
Dict{Int64,Int64} with 6 entries:
  4 => 8
  2 => 27
  3 => 64
  5 => 27
  6 => 64
  1 => 8

我给了你一个答案,但如果你能用
hello\u world
函数替换代码中的
count\u proteins
,那将是对你身边的读者的极大礼貌。以后别人会更容易阅读。没错,我会的。谢谢你的回答@Przemyslaw Szufel。正如您从标题中看到的,我使用的是
@spawn
,而不是
@spawnat
,这需要工作者ID。不管怎样,它都会起作用。您可以更改
@spawn
并避免返回工作ID吗。我的意思是你可以在不知道工人ID的情况下提取吗?是的,你可以(我编辑了这个示例),但通常最好自己管理,或者使用
@分布式
循环。请注意,
未来
对象的
.where
字段中也存在工作者id。是的,我同意这通常更好,但在某些情况下,我可能不需要知道工作者id:)