目前 LTS=1.6.4, master=1.8 的建议是:
可以用,不会报错。但内层的多线程会变成单线程,对性能没有帮助。
实际上只有最外层的会并行。
后续的版本可能有新的变化。
参考资料
jeff 的评论
From triage: disable parallelism when nested.
—— jeff#35646
注:triage
指定期的多人电话会议讨论,可以视作开发团队的决定。
What does the “triage” tag on Github mean? - Community - JuliaLang
master (1.8) 的代码
if threadid() != 1 || ccall(:jl_in_threaded_region, Cint, ()) != 0
$(if schedule === :static
:(error("`@threads :static` can only be used from thread 1 and not nested"))
else
# only use threads when called from thread 1, outside @threads
:(Base.invokelatest(threadsfor_fun, true))
end)
else
threading_run(threadsfor_fun)
end
这段代码的意思是,当嵌套多线程宏时,内部的嵌套全部以单线程运行(多了个 onethread=true 的参数)。
threadid() == 1
标志着是最外层的 @threads
宏调用。因为仅有用户所在的线程 id 才为 1.
英文社区的讨论
General Usage
Performance
Hi, I am wondering how to apply multi-threading to nested for loops. For the function nestedloop below, I guess the threads will only be launched for the outermost k loop for OMP_JULIA_THREADS times: function nestedloops(nx, ny, nz) state =...
Reading time: 18 mins 🕑
Likes: 51 ❤
扩展阅读
ThreadsX.jl is aiming at providing API compatible with Base functions optimized for multicore machines. tl;dr Quoting tl;dr section of README: Add prefix ThreadsX. to functions from Base to get some speedup, if supported. Example: using...
Reading time: 16 mins 🕑
Likes: 139 ❤
Jeff 2021 - Multi-Threading Using Julia for Enterprises - YouTube
This webinar will demonstrate how to take advantage of the ever-increasing core counts in modern CPUs using Julia. The language provides simple loop-based and nested task-based parallelism, making multi-threaded programming easier than ever. Once you try it, you’re sure to want more cores, and for that we will demonstrate JuliaHub, where you can start up to 32 vCPUs in a single node with just a couple clicks.
3 个赞
那篇英文社区的链接帖起始于我以前测试时遇到的性能问题。我对多线程的了解起源于OpenMP,而在OpenMP中经过多年发展像这种线程嵌套相对非常成熟了,切换到Julia中就会发现很多相对的性能问题,比如overhead,thread migration,以及远不如OpenMP灵活的variable scope declaration for avoiding race conditions.
Julia目前的1.7版本一个重大改变是多线程任务可以发生迁移了,而不用绑定在一开始分配的core上面。我还没有很好的测试例子能说明这能带来多大的性能提升。但是根据我的理解,目前的一大瓶颈在于garbage collector并不是多线程的,而是所有线程共享的,所以如果程序的多线程部分有较多的内存开销,仍然会有明显的性能问题。
关于thread launching overhead,目前开发中号称最少代价的包是由LoopVectorization.jl的作者开发的 JuliaSIMD/Polyester.jl: The cheapest threads you can find! (github.com) 。但是这个包提供的线程方式是不如Threads.@threads
通用的。
目前的一大瓶颈在于garbage collector并不是多线程的,而是所有线程共享的
但是在线程模型里面,内存就是由线程共享的呀,所以在一个线程上 GC 其实就会影响到其他线程呀… 如果想要内存隔离的话,那应该就需要使用多进程的模式了…
你这么一说的确,像OpenMP支持的Fortran, C/C++,都没有使用GC。所以我不知道GC是否天然地和线程犯冲。
说到 GC 那就得学学 JVM 了。
不过 julia 提倡计算密集时,预分配好内存。
所以 GC 相关的改进,没人推进就一直会这样。