I was surprised at how big a hit we suffer in looking up the THREAD_RNG — even when Julia is started with only 1 thread and without using @threads at all! Is there something we can do here?
julia> using Random, .Threads
julia> nthreads()
1
julia> function serialpi(n)
inside = 0
for i in 1:n
x, y = rand(), rand()
inside += (x^2 + y^2 <= 1)
end
return 4 * inside / n
end
serialpi (generic function with 1 method)
julia> serialpi(1); @time serialpi(100_000_000);
0.625890 seconds
julia> function serialpi2(n)
inside = 0
rng = Random.THREAD_RNGs[1]
for i in 1:n
x, y = rand(rng), rand(rng)
inside += (x^2 + y^2 <= 1)
end
return 4 * inside / n
end
serialpi2 (generic function with 1 method)
julia> serialpi2(1); @time serialpi2(100_000_000);
0.257850 seconds
Ah, I knew we had this before — Kristoffer search is the best GitHub search.
Still, I feel like this is a slightly more constrained case; do we really need to be paying the cost of this indirection with nthreads()==1?
It'd be great if the compiler can hoist out the lookup for rng. It'd also help "context variables" as designed in #35833.
Ah, yeah, this is the reason I had before why thread local variable can't be replaced with task local and why caching of thread local variable can't be disabled. Unless there's a way to make RNG still work equally well when many more are created and destroied on the fly. Ref https://github.com/JuliaLang/julia/issues/35688
Most helpful comment
Ah, I knew we had this before — Kristoffer search is the best GitHub search.
Still, I feel like this is a slightly more constrained case; do we really need to be paying the cost of this indirection with nthreads()==1?