Status of Threads

Does anyone know what the status of threads are? The following either terminates or hangs Julia 0.5.1 depending on N. I can’t use processes because I’m calling into a C routine that needs all memory in a single process space.

Threads.@threads for i = 1:N; println(Threads.threadid()); end
1 Like

IO is the main part that isn’t thread safe. So don’t use Base.print. Core.print might work better although I don’t think it’s using all the safe path either.

Ref https://github.com/JuliaLang/julia/pull/21893

Thanks, that fixes the problem. I seem to be limited to 8 threads. Is there any way to get more?

Actually, thinking about this a bit more. If I don’t have any guarantee about mapping between iteration index and threads, I might have to manually manage the threads anyway; so, number of threads isn’t that important.

Is codegen supposed to be threadsafe now (v0.6-rc) ? I recently encountered some crashes when trying to use SIMD.jl constructs in threaded loops, but when I saw that SIMD.jl uses @generated functions I thought that was a known problem.

Get a better machine? I think we don’t allow oversubscription for now.

You shouldn’t do that unless you really have to and know exactly what you are doing.

It should have enough locks.

Thanks. I’ll have to give this some more thought. At the very least, I need to know that all nthreads() are used to iterate over the loop; otherwise, the C call will hang.

FYI that’ll not be the model we have. We’ll have a model closer to cilk where (at the highest level, it is ok if the runtie decides to not run your code on other threads and run it sequentially)

1 Like

Yes, I was assuming that was the case. It might be good idea to add it to the docs (for threads and processes) though as it might not be obvious to others.

I think I can solve this by moving synchronization primitives out of C and into Julia. Then there’s no dependency on the semantics of threading applied to loops. I will still have to find a work around for nested loops. Can someone explain the difference between comma and semicolon in the following?

julia> for i = 1:64; j = 1:32; b[i,j]=Threads.threadid(); end;
julia> for i = 1:64, j = 1:32; b[i,j]=Threads.threadid(); end;
julia> Threads.@threads for i = 1:64; j = 1:32; b[i,j]=Threads.threadid(); end
julia> Threads.@threads for i = 1:64, j = 1:32; b[i,j]=Threads.threadid(); end
ERROR: syntax: invalid assignment location "i=1:64"

; is a new line.

Off-topic: @yuyichao is the timeline for Threads release scheduled to release with 1.0? Also, I am meaning to learn about Cilk parallelism with the book “Structured Parallel Programming” by Arch Robison et al - is that a good primer? Thanks for any advice!

I’m not sure about the precise timeline (I’m not doing it) but I believe we are aiming for a more flexible and usable API in 1.0. It may not include dynamically adding worker or unmanaged thread. We are working on making the runtime safer in general. The biggest problem there is IO and I’m not aware of a timeline or agreed solution.

I’m mainly working on low level thread safety stuff and not much about scheduling so I can’t give any advice on learning cilk…

1 Like

Thanks a million. Do you know where/who I should direct these questions to instead?

I recommend wait here or start another topic… There might be other forum with more knowledgeable people about multithreading but I’m not sure…

1 Like

I don’t need any further help. I happened to notice the following odd behavior. Usually unbound symbol throws an error. I’m not sure if stderr is just being re-directed, but it hangs when only b is unbound, and seems to work otherwise.

# a and b not yet bound
julia> Threads.@threads for i = 1:64 j = 1:32; lock(a); b[i,j]=Threads.threadid(); unlock(a); end
julia> a=Threads.Mutex()
Base.Threads.Mutex(0,Ptr{Void} @0x000000000bc4a2b0)
# Next line hangs when only b is not bound
julia> Threads.@threads for i = 1:64 j = 1:32; lock(a); b[i,j]=Threads.threadid(); unlock(a); end

You are throwing an error without unlocking the lock.

OK I see what’s going on. Is there a thread-safe way to re-direct output so I can observe errors?

Errors should be printed on 0.6.