I do not understand the logic in this post (PSA: Thread-local state is no longer recommended).
- in the first sample you are using the
@threads-pattern for incorrect code, which is hardly reproducible for incorrect results. - in the second sample you are using the
@sync-@spawn-pattern to demonstrate the incorrectness, which is surely reproducible for incorrect results.
Could you please give an easily reproducible sample using the @threads-pattern for incorrect results?
Thank!
Here are some details about my tests of @threads-pattern and @sync-@spawn-pattern.
In the section “The buggy pattern” in this Blog (PSA: Thread-local state is no longer recommended) it reads
“The general template that this incorrect code follows is something like the following:” (then the @threads-pattern code).
The following Julia code using the general template (as mentioned in the Blog) is repeatedly tested via julia -t 7 threads.jl in a bash for-loop. However, the output does not change in different runs (at least in my tests).
using Base.Threads: nthreads, @threads, threadid
f(i) = (sleep(0.001); i)
states = [ 0 for _ in 1:nthreads() ]
N = 100
@threads for x in 1:N
tid = threadid()
old_val = states[tid]
new_val = old_val + f(x)
states[tid] = new_val
end
@show sum(states)
For the @sync-@spawn-pattern (the 2nd example in the Blog): the following Julia code is repeatedly tested via julia -t 7 spawn.jl in a bash for-loop. The output does change very frequently in different runs.
using Base.Threads: nthreads, @spawn, threadid
f(i) = (sleep(0.001); i)
let states = [ 0 for _ in 1:nthreads() ], N = 100
@sync for i in 1:N
@spawn begin
tid = threadid()
old_val = states[tid]
new_val = old_val + f(i)
states[tid] = new_val
end
end
@show sum(states)
end
Thus, I mean the general template in the Blog is not reproducible. The @threads-pattern code above always gives correct results in my tests. More info about my tests:
- CPU: AMD EPYC 7763 64-Core
- OS: Red Hat Enterprise Linux 8.8
- Julia: version 1.10.2