* @brief Manually set CPU group and thread affinity. * * This is needed on Windows 10 or older to allow benefit from large core count * systems with more than 64 logical CPUs. The assignment is skipped on systems * with a single processor group, as it is not necessary. */
| 86 | * with a single processor group, as it is not necessary. |
| 87 | */ |
| 88 | static void set_group_affinity( |
| 89 | pthread_t thread, |
| 90 | int thread_index |
| 91 | ) { |
| 92 | // Skip thread assignment for hardware with a single CPU group |
| 93 | int group_count = GetActiveProcessorGroupCount(); |
| 94 | if (group_count == 1) |
| 95 | { |
| 96 | return; |
| 97 | } |
| 98 | |
| 99 | // Ensure we have a valid assign if user creates more threads than cores |
| 100 | int assign_index = thread_index % get_cpu_count(); |
| 101 | int assign_group { 0 }; |
| 102 | int assign_group_cpu_count { 0 }; |
| 103 | |
| 104 | // Determine which core group and core in the group to use for this thread |
| 105 | int group_cpu_count_sum { 0 }; |
| 106 | for (int group = 0; group < group_count; group++) |
| 107 | { |
| 108 | int group_cpu_count = static_cast<int>(GetMaximumProcessorCount(group)); |
| 109 | group_cpu_count_sum += group_cpu_count; |
| 110 | |
| 111 | if (assign_index < group_cpu_count_sum) |
| 112 | { |
| 113 | assign_group = group; |
| 114 | assign_group_cpu_count = group_cpu_count; |
| 115 | break; |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | // Set the affinity to the assigned group, and all supported cores |
| 120 | GROUP_AFFINITY affinity {}; |
| 121 | affinity.Mask = (1 << assign_group_cpu_count) - 1; |
| 122 | affinity.Group = assign_group; |
| 123 | SetThreadGroupAffinity(thread, &affinity, nullptr); |
| 124 | } |
| 125 | |
| 126 | /** |
| 127 | * @brief Proxy Windows @c WaitForSingleObject underneath a pthreads-like wrapper. |
no test coverage detected