-
Notifications
You must be signed in to change notification settings - Fork 4.5k
fix: support >64 CPUs on Windows via processor groups (#6142) #6823
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
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1373,11 +1373,11 @@ static ncnn::CpuSet get_smt_cpu_mask() | |
| if (ptr->Relationship == RelationProcessorCore) | ||
| { | ||
| ncnn::CpuSet smt_set; | ||
| smt_set.mask = ptr->ProcessorMask; | ||
| smt_set.mask[0] = ptr->ProcessorMask; | ||
| if (smt_set.num_enabled() > 1) | ||
| { | ||
| // this core is smt | ||
| smt_cpu_mask.mask |= smt_set.mask; | ||
| smt_cpu_mask.mask[0] |= smt_set.mask[0]; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -1432,14 +1432,43 @@ static std::vector<int> get_max_freq_mhz() | |
|
|
||
| static int set_sched_affinity(const ncnn::CpuSet& thread_affinity_mask) | ||
| { | ||
| DWORD_PTR prev_mask = SetThreadAffinityMask(GetCurrentThread(), thread_affinity_mask.mask); | ||
| if (prev_mask == 0) | ||
| // Find the first enabled CPU group and bind this thread to it. | ||
| // A thread can only belong to one processor group at a time. | ||
| // For multi-group masks, set_cpu_thread_affinity() calls this | ||
| // repeatedly per-thread, each bound to a specific group. | ||
| for (int g = 0; g < NCNN_MAX_PROCESSOR_GROUPS; g++) | ||
| { | ||
| NCNN_LOGE("SetThreadAffinityMask failed %d", GetLastError()); | ||
| return -1; | ||
| if (thread_affinity_mask.mask[g] == 0) | ||
| continue; | ||
|
|
||
| #if _WIN32_WINNT >= 0x0600 // Win7+ | ||
| GROUP_AFFINITY ga; | ||
| ga.Group = (WORD)g; | ||
| ga.Mask = thread_affinity_mask.mask[g]; | ||
| ga.Reserved[0] = 0; | ||
| ga.Reserved[1] = 0; | ||
| ga.Reserved[2] = 0; | ||
|
|
||
| GROUP_AFFINITY prev; | ||
| if (!SetThreadGroupAffinity(GetCurrentThread(), &ga, &prev)) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When building the repository's Windows XP configurations ( Useful? React with 👍 / 👎. |
||
| { | ||
| NCNN_LOGE("SetThreadGroupAffinity failed for group %d: %d", g, GetLastError()); | ||
| return -1; | ||
| } | ||
| #else // XP: only group 0 supported, use legacy API | ||
| if (g != 0) | ||
| continue; // XP cannot bind beyond group 0 | ||
| DWORD_PTR prev = SetThreadAffinityMask(GetCurrentThread(), thread_affinity_mask.mask[0]); | ||
| if (prev == 0) | ||
| { | ||
| NCNN_LOGE("SetThreadAffinityMask failed %d", GetLastError()); | ||
| return -1; | ||
| } | ||
| #endif | ||
| return 0; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When the affinity mask spans multiple Windows processor groups, this early return binds every caller to only the first non-empty group. Useful? React with 👍 / 👎. |
||
| } | ||
|
|
||
| return 0; | ||
| return 0; // no CPUs enabled | ||
| } | ||
| #endif // defined _WIN32 | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,10 @@ | |
|
|
||
| #include "platform.h" | ||
|
|
||
| // Windows processor groups each contain up to 64 logical processors. | ||
| // Support up to NCNN_MAX_PROCESSOR_GROUPS groups (512 CPUs max at 8 groups). | ||
| #define NCNN_MAX_PROCESSOR_GROUPS 8 | ||
|
|
||
| namespace ncnn { | ||
|
|
||
| class NCNN_EXPORT CpuSet | ||
|
|
@@ -30,7 +34,7 @@ class NCNN_EXPORT CpuSet | |
|
|
||
| public: | ||
| #if defined _WIN32 | ||
| ULONG_PTR mask; | ||
| KAFFINITY mask[NCNN_MAX_PROCESSOR_GROUPS]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In the current tree, changing Useful? React with 👍 / 👎. |
||
| #endif | ||
| #if defined __ANDROID__ || defined __linux__ | ||
| cpu_set_t cpu_set; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fresh evidence beyond the prior XP concern: this revision added a guard, but it still takes this branch when
_WIN32_WINNT == 0x0600(Vista), whileSetThreadGroupAffinityis only available for_WIN32_WINNT >= 0x0601/ Windows 7. A Vista-targeted non-XP build therefore compiles or links against a missing API instead of using the legacySetThreadAffinityMaskfallback; use the Win7 threshold or a runtime lookup here.Useful? React with 👍 / 👎.