-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
win: uv_available_parallelism
doesn't respect process affinity
#4520
Comments
The Windows implementation of Are you saying it should use |
I guess so, since the Linux implementation seems to do the equivalent of that, and I believe it'd more closely match the "available" parallelism. |
Does this patch work like you expect it to? diff --git a/src/win/util.c b/src/win/util.c
index deed2e35..c667eea8 100644
--- a/src/win/util.c
+++ b/src/win/util.c
@@ -512,19 +512,22 @@ int uv_uptime(double* uptime) {
unsigned int uv_available_parallelism(void) {
- SYSTEM_INFO info;
- unsigned rc;
+ DWORD_PTR procmask;
+ int count;
+ int i;
/* TODO(bnoordhuis) Use GetLogicalProcessorInformationEx() to support systems
* with > 64 CPUs? See https://github.com/libuv/libuv/pull/3458
*/
- GetSystemInfo(&info);
+ count = 0;
+ if (GetProcessAffinityMask(GetCurrentProcess(), &procmask, NULL))
+ for (i = 0; i < 64; i++) /* a.k.a. count = popcount(procmask); */
+ count += 1 & (procmask >> i);
- rc = info.dwNumberOfProcessors;
- if (rc < 1)
- rc = 1;
+ if (count > 0)
+ return count;
- return rc;
+ return 1;
}
|
I can't test that exactly because I don't have a Windows environment set up with a compiler to build libuv and Julia, but I can test the syscalls from julia: julia> procmask = Ref(UInt64(0))
Base.RefValue{UInt64}(0x0000000000000000)
julia> sysmask = Ref(UInt64(0))
Base.RefValue{UInt64}(0x0000000000000000)
julia> @ccall GetProcessAffinityMask(@ccall(GetCurrentProcess()::Ptr{Cvoid})::Ptr{Cvoid}, procmask::Ptr{UInt64}, sysmask::Ptr{UInt64})::Cint
1
julia> count_ones(procmask[])
4
julia> run(setcpuaffinity(`julia -q`, 1:2));
julia> procmask = Ref(UInt64(0))
Base.RefValue{UInt64}(0x0000000000000000)
julia> sysmask = Ref(UInt64(0))
Base.RefValue{UInt64}(0x0000000000000000)
julia> @ccall GetProcessAffinityMask(@ccall(GetCurrentProcess()::Ptr{Cvoid})::Ptr{Cvoid}, procmask::Ptr{UInt64}, sysmask::Ptr{UInt64})::Cint
1
julia> count_ones(procmask[])
2 In the outer process (without restrictions), |
Use GetProcessAffinityMask() to estimate the available parallelism. Before this commit, it simply used the number of available CPUs. Fixes: libuv#4520
Use GetProcessAffinityMask() to estimate the available parallelism. Before this commit, it simply used the number of available CPUs. Fixes: libuv#4520
Use GetProcessAffinityMask() to estimate the available parallelism. Before this commit, it simply used the number of available CPUs. Fixes: libuv#4520 (cherry picked from commit 58dfb6c)
Use GetProcessAffinityMask() to estimate the available parallelism. Before this commit, it simply used the number of available CPUs. Fixes: libuv#4520 (cherry picked from commit 58dfb6c)
Sorry, this is a full Julia report, but it involves only libuv functions. The problem is that on Windows, but not on Linux,
uv_available_parallelism
doesn't respect process affinity, contrary touv_thread_getaffinity
, returning total number of logical threads available in the system:I'm using
setcpuaffinity
to set the affinity of the process and limit it two cores, I'm loading thetest/print_process_affinity.jl
script which defines a small wrapper arounduv_thread_getaffinity
, and I'm also printing Julia'sSys.CPU_THREAD
to show the total number of logical threads on the system.On Linux I get
as expected.
Current build of libuv used in Julia is based on libuv v1.48.0. CC: @vtjnash.
The text was updated successfully, but these errors were encountered: