分布式计算 #

一、分布式基础 #

1.1 启动工作进程 #

julia
using Distributed

addprocs(4)
nprocs()
workers()
rmprocs(workers())

1.2 启动时指定 #

bash
julia -p 4

1.3 远程执行 #

julia
using Distributed

addprocs(2)

r = remotecall(() -> myid(), 2)
fetch(r)

remotecall_fetch(() -> myid(), 2)

二、远程调用 #

2.1 remotecall #

julia
using Distributed

addprocs(2)

r = remotecall((x) -> x^2, 2, 5)
fetch(r)

2.2 remotecall_wait #

julia
remotecall_wait((x) -> x^2, 2, 5)

2.3 remotecall_fetch #

julia
remotecall_fetch((x) -> x^2, 2, 5)

2.4 @spawn #

julia
using Distributed

addprocs(2)

r = @spawn sum(rand(1000))
fetch(r)

2.5 @spawnat #

julia
r = @spawnat 2 sum(rand(1000))
fetch(r)

三、数据传输 #

3.1 远程引用 #

julia
using Distributed

addprocs(2)

r = remotecall(() -> rand(5), 2)
typeof(r)
fetch(r)

3.2 远程通道 #

julia
using Distributed

addprocs(2)

ch = RemoteChannel(() -> Channel{Int}(10))

put!(ch, 1)
take!(ch)

3.3 共享数据 #

julia
using Distributed

addprocs(2)

@everywhere data = [1, 2, 3, 4, 5]

r = @spawn sum(data)
fetch(r)

四、并行映射 #

4.1 pmap #

julia
using Distributed

addprocs(2)

pmap(x -> x^2, [1, 2, 3, 4, 5])

4.2 @distributed #

julia
using Distributed

addprocs(2)

@distributed (+) for i in 1:100
    i^2
end

4.3 分布式循环 #

julia
using Distributed

addprocs(2)

@distributed for i in 1:10
    println("Worker $(myid()) processing $i")
end

五、实践练习 #

5.1 练习1:并行计算 #

julia
using Distributed

addprocs(4)

function parallel_sum(arr)
    @distributed (+) for x in arr
        x
    end
end

parallel_sum(1:10^6)

5.2 练习2:并行蒙特卡洛 #

julia
using Distributed

addprocs(4)

@everywhere function monte_carlo_pi(n)
    hits = 0
    for _ in 1:n
        x, y = rand(), rand()
        if x^2 + y^2 <= 1
            hits += 1
        end
    end
    return hits
end

function parallel_monte_carlo_pi(total_n)
    n_per_worker = total_n ÷ nworkers()
    results = pmap(_ -> monte_carlo_pi(n_per_worker), 1:nworkers())
    total_hits = sum(results)
    return 4 * total_hits / total_n
end

parallel_monte_carlo_pi(10^7)

5.3 练习3:分布式任务队列 #

julia
using Distributed

addprocs(2)

function distributed_queue(jobs)
    results = RemoteChannel(() -> Channel{Any}(length(jobs)))
    
    @async begin
        for job in jobs
            put!(results, @spawn process_job(job))
        end
    end
    
    return [fetch(take!(results)) for _ in 1:length(jobs)]
end

@everywhere function process_job(x)
    sleep(0.1)
    x^2
end

distributed_queue([1, 2, 3, 4, 5])

六、总结 #

本章我们学习了:

  1. 分布式基础:addprocs和workers
  2. 远程调用:remotecall、@spawn
  3. 数据传输:远程引用和通道
  4. 并行映射:pmap和@distributed

接下来让我们学习Julia的元编程!

最后更新:2026-03-27