我在并行编程方面没有太多经验。但是,当我尝试并行运行 Julia 代码时遇到了一个有趣的情况。
@threads for i in 1:THREADS
run(parameters[i], tm)
end
parameter::Vector{Parameters} 是可变结构体的向量,tm 是每个线程的终止时间。没有原子变量。 THREADS变量的不同值的平均迭代次数如下:
THREADS Itertations
1 35087
2 44079
3 50220
4 43701
5 39624
6 38986
7 34625
8 35810
9 29248
10 28075
11 20376
12 27342
当 THREAD=3 时,观察到计算次数最多。我的 CPU 是 Apple M2 Pro 12 核 3480 MHz。我必须注意, run(.,.) 函数包含遗传算法过程,它会在内存中创建和删除太多对象。所以我怀疑这是由 Julia 的垃圾收集系统引起的。如果您对为什么 THREAD=3 时达到峰值有任何想法,我很想知道。谢谢你。
不幸的是,当有很多线程时,Julia 的垃圾收集器效率不高。据我所知,这正在从一个版本到另一个版本进行改进,例如。从 1.9 升级到今天发布的 1.10 可能会带来一些性能提升。
根据经验,使用分配大量资源的大规模并行代码的最佳方法是使用多处理而不是多线程。您应该观察到显着的性能提升:
using Distributed
addprocs(12)
@everywhere using MyPackage
@sync @distributed for i in 1:nworkers()
run(parameters[i], tm)
end
或者取决于结果聚合模式:
@everywhere using MyPackage, DataFrames
@distributed (append!) for i in 1:nworkers()
res = run(parameters[i], tm)
DataFrame(;res)
end