-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Option to pin GC threads #53073
Comments
Because I'm giving a Julia course at UCL this week, I couldn't implement this before 1.11 feature freeze (today), which is a bit sad. If I implement this next week, is there any chance that we can still get this into 1.11? |
I believe so, if the code isn't super complex (I don't believe it would be) |
I'm trying to implement this but I have a problem. AFAICS, we don't seem to store the thread handles ( Note that OpenBLAS stores these handles and it was thus pretty easy to add affinity functions, e.g. https://github.com/OpenMathLib/OpenBLAS/pull/3702/files#diff-2b77a530a65c94d60feb21d4ce2093df0a2bd3cb710d2dc82bab32f18e1c963a. Should I add a new storage for them or is there a different/better way to get the handles? (@gbaraldi) |
Note to self: Ok, seems like we are storing the information in the TLS (specifically, in the field |
This PR adds two functions `jl_getaffinity` and `jl_setaffinity` to the runtime, which are slim wrappers around `uv_thread_getaffinity` and `uv_thread_setaffinity` and can be used to set the affinity of Julia threads. This will * simplify thread pinning (ThreadPinning.jl currently pins threads by spawning tasks that run the necessary ccalls) and * enable users to also pin GC threads (or, more generally, all Julia threads). **Example:** ```julia bauerc@n2lcn0146 julia git:(cb/affinity) ➜ ./julia -q --startup-file=no --threads 2,3 --gcthreads 4,1 julia> cpumasksize = @CCall uv_cpumask_size()::Cint 1024 julia> mask = zeros(Cchar, cpumasksize); julia> jl_getaffinity(tid, mask, cpumasksize) = ccall(:jl_getaffinity, Int32, (Int16, Ptr{Cchar}, Int32), tid, mask, cpumasksize) jl_getaffinity (generic function with 1 method) julia> jl_getaffinity(1, mask, cpumasksize) 0 julia> print(mask[1:Sys.CPU_THREADS]) Int8[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] julia> mask[1] = 0; julia> jl_setaffinity(tid, mask, cpumasksize) = ccall(:jl_setaffinity, Int32, (Int16, Ptr{Cchar}, Int32), tid, mask, cpumasksize) jl_setaffinity (generic function with 1 method) julia> jl_setaffinity(1, mask, cpumasksize) 0 julia> fill!(mask, 0); julia> jl_getaffinity(1, mask, cpumasksize) 0 julia> print(mask[1:Sys.CPU_THREADS]) Int8[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ``` (cc @vchuravy, @gbaraldi) Would be great to get this into 1.11 (despite feature freeze) because otherwise we won't be able to pin GC threads until 1.12 (likely not until the end of the year). Closes #53073 --------- Co-authored-by: Valentin Churavy <[email protected]> Co-authored-by: Dilum Aluthge <[email protected]>
This PR adds two functions `jl_getaffinity` and `jl_setaffinity` to the runtime, which are slim wrappers around `uv_thread_getaffinity` and `uv_thread_setaffinity` and can be used to set the affinity of Julia threads. This will * simplify thread pinning (ThreadPinning.jl currently pins threads by spawning tasks that run the necessary ccalls) and * enable users to also pin GC threads (or, more generally, all Julia threads). **Example:** ```julia bauerc@n2lcn0146 julia git:(cb/affinity) ➜ ./julia -q --startup-file=no --threads 2,3 --gcthreads 4,1 julia> cpumasksize = @CCall uv_cpumask_size()::Cint 1024 julia> mask = zeros(Cchar, cpumasksize); julia> jl_getaffinity(tid, mask, cpumasksize) = ccall(:jl_getaffinity, Int32, (Int16, Ptr{Cchar}, Int32), tid, mask, cpumasksize) jl_getaffinity (generic function with 1 method) julia> jl_getaffinity(1, mask, cpumasksize) 0 julia> print(mask[1:Sys.CPU_THREADS]) Int8[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] julia> mask[1] = 0; julia> jl_setaffinity(tid, mask, cpumasksize) = ccall(:jl_setaffinity, Int32, (Int16, Ptr{Cchar}, Int32), tid, mask, cpumasksize) jl_setaffinity (generic function with 1 method) julia> jl_setaffinity(1, mask, cpumasksize) 0 julia> fill!(mask, 0); julia> jl_getaffinity(1, mask, cpumasksize) 0 julia> print(mask[1:Sys.CPU_THREADS]) Int8[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ``` (cc @vchuravy, @gbaraldi) Would be great to get this into 1.11 (despite feature freeze) because otherwise we won't be able to pin GC threads until 1.12 (likely not until the end of the year). Closes #53073 --------- Co-authored-by: Valentin Churavy <[email protected]> Co-authored-by: Dilum Aluthge <[email protected]>
This PR adds two functions `jl_getaffinity` and `jl_setaffinity` to the runtime, which are slim wrappers around `uv_thread_getaffinity` and `uv_thread_setaffinity` and can be used to set the affinity of Julia threads. This will * simplify thread pinning (ThreadPinning.jl currently pins threads by spawning tasks that run the necessary ccalls) and * enable users to also pin GC threads (or, more generally, all Julia threads). **Example:** ```julia bauerc@n2lcn0146 julia git:(cb/affinity) ➜ ./julia -q --startup-file=no --threads 2,3 --gcthreads 4,1 julia> cpumasksize = @CCall uv_cpumask_size()::Cint 1024 julia> mask = zeros(Cchar, cpumasksize); julia> jl_getaffinity(tid, mask, cpumasksize) = ccall(:jl_getaffinity, Int32, (Int16, Ptr{Cchar}, Int32), tid, mask, cpumasksize) jl_getaffinity (generic function with 1 method) julia> jl_getaffinity(1, mask, cpumasksize) 0 julia> print(mask[1:Sys.CPU_THREADS]) Int8[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] julia> mask[1] = 0; julia> jl_setaffinity(tid, mask, cpumasksize) = ccall(:jl_setaffinity, Int32, (Int16, Ptr{Cchar}, Int32), tid, mask, cpumasksize) jl_setaffinity (generic function with 1 method) julia> jl_setaffinity(1, mask, cpumasksize) 0 julia> fill!(mask, 0); julia> jl_getaffinity(1, mask, cpumasksize) 0 julia> print(mask[1:Sys.CPU_THREADS]) Int8[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ``` (cc @vchuravy, @gbaraldi) Would be great to get this into 1.11 (despite feature freeze) because otherwise we won't be able to pin GC threads until 1.12 (likely not until the end of the year). Closes #53073 --------- Co-authored-by: Valentin Churavy <[email protected]> Co-authored-by: Dilum Aluthge <[email protected]> (cherry picked from commit 065aeb6)
This PR adds two functions `jl_getaffinity` and `jl_setaffinity` to the runtime, which are slim wrappers around `uv_thread_getaffinity` and `uv_thread_setaffinity` and can be used to set the affinity of Julia threads. This will * simplify thread pinning (ThreadPinning.jl currently pins threads by spawning tasks that run the necessary ccalls) and * enable users to also pin GC threads (or, more generally, all Julia threads). **Example:** ```julia bauerc@n2lcn0146 julia git:(cb/affinity) ➜ ./julia -q --startup-file=no --threads 2,3 --gcthreads 4,1 julia> cpumasksize = @CCall uv_cpumask_size()::Cint 1024 julia> mask = zeros(Cchar, cpumasksize); julia> jl_getaffinity(tid, mask, cpumasksize) = ccall(:jl_getaffinity, Int32, (Int16, Ptr{Cchar}, Int32), tid, mask, cpumasksize) jl_getaffinity (generic function with 1 method) julia> jl_getaffinity(1, mask, cpumasksize) 0 julia> print(mask[1:Sys.CPU_THREADS]) Int8[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] julia> mask[1] = 0; julia> jl_setaffinity(tid, mask, cpumasksize) = ccall(:jl_setaffinity, Int32, (Int16, Ptr{Cchar}, Int32), tid, mask, cpumasksize) jl_setaffinity (generic function with 1 method) julia> jl_setaffinity(1, mask, cpumasksize) 0 julia> fill!(mask, 0); julia> jl_getaffinity(1, mask, cpumasksize) 0 julia> print(mask[1:Sys.CPU_THREADS]) Int8[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ``` (cc @vchuravy, @gbaraldi) Would be great to get this into 1.11 (despite feature freeze) because otherwise we won't be able to pin GC threads until 1.12 (likely not until the end of the year). Closes JuliaLang#53073 --------- Co-authored-by: Valentin Churavy <[email protected]> Co-authored-by: Dilum Aluthge <[email protected]>
I would like to add the ability to pin GC threads to ThreadPinning.jl. AFAICS, we (a user) can't run Julia code on GC threads. Hence, I think we need to add something like https://github.com/OpenMathLib/OpenBLAS/blob/4d0b7fbec04c95c90291938a5974f00673e10e68/driver/others/blas_server.c#L341-L369 to the C runtime.
Would it be possible/accepted to add such functions?
(cc @vchuravy)
PS: IIUC, we can't add this retrospectively to 1.10 but it would be great to get it into 1.11.
The text was updated successfully, but these errors were encountered: