__declspec(dllexport) int __cdecl GetPhysicalProcessorCount() { ULONG p; if (GetNumaHighestNodeNumber(&p)) return (int)p + 1; else return 1; }
mask_type init_thread_affinity_mask( std::size_t num_thread , bool numa_sensitive ) { // {{{ std::size_t num_of_cores = hardware_concurrency(); std::size_t affinity = num_thread % num_of_cores; ULONG numa_nodes = 1; if (GetNumaHighestNodeNumber(&numa_nodes)) ++numa_nodes; std::size_t num_of_cores_per_numa_node = num_of_cores / numa_nodes; ULONGLONG node_affinity_mask = 0; ULONGLONG mask = 0x01LL; if (numa_sensitive) { UCHAR numa_node = UCHAR(affinity % numa_nodes); if (!GetNumaNodeProcessorMask(numa_node, &node_affinity_mask)) { HPX_THROW_EXCEPTION(kernel_error , "hpx::threads::windows_topology::init_thread_affinity_mask" , boost::str(boost::format( "failed to initialize thread %1% affinity mask") % num_thread)); } mask = least_significant_bit(node_affinity_mask) << (affinity / numa_nodes); } else { UCHAR numa_node = UCHAR(get_numa_node_number(num_thread)); if (!GetNumaNodeProcessorMask(numa_node, &node_affinity_mask)) { HPX_THROW_EXCEPTION(kernel_error , "hpx::threads::windows_topology::init_thread_affinity_mask" , boost::str(boost::format( "failed to initialize thread %1% affinity mask") % num_thread)); } mask = least_significant_bit(node_affinity_mask) << (affinity % num_of_cores_per_numa_node); } while (!(mask & node_affinity_mask)) { mask <<= 1LL; if (0 == mask) mask = 0x01LL; } return static_cast<mask_type>(mask); } // }}}
uint32_t osNumaNodes(void) { /* Cache the amount of NUMA values. */ static ULONG numNumaNodes = 0; /* Cache the amount of NUMA nodes. */ if (!numNumaNodes && !GetNumaHighestNodeNumber(&numNumaNodes)) { numNumaNodes = 1; } return numNumaNodes; }
/* static */ int ThreadPool::getNumaNodeCount() { #if defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_WIN7 ULONG num = 1; if (GetNumaHighestNodeNumber(&num)) num++; return (int)num; #elif HAVE_LIBNUMA if (numa_available() >= 0) return numa_max_node() + 1; else return 1; #else return 1; #endif }
mask_type init_numa_node_affinity_mask( std::size_t num_thread , bool numa_sensitive ) { // {{{ std::size_t num_of_cores = hardware_concurrency(); UCHAR affinity = UCHAR(num_thread % num_of_cores); ULONG numa_nodes = 1; if (GetNumaHighestNodeNumber(&numa_nodes)) ++numa_nodes; ULONGLONG mask = 0; if (numa_sensitive) { UCHAR numa_node = affinity % numa_nodes; if (!GetNumaNodeProcessorMask(numa_node, &mask)) { HPX_THROW_EXCEPTION(kernel_error , "hpx::threads::windows_topology::init_numa_node_affinity_mask" , boost::str(boost::format( "failed to initialize NUMA node affinity mask for " "thread %1%") % num_thread)); } return static_cast<mask_type>(mask); } UCHAR numa_node = UCHAR(get_numa_node_number(num_thread)); if (!GetNumaNodeProcessorMask(numa_node, &mask)) { HPX_THROW_EXCEPTION(kernel_error , "hpx::threads::windows_topology::init_numa_node_affinity_mask" , boost::str(boost::format( "failed to initialize NUMA node affinity mask for " "thread %1%") % num_thread)); } return static_cast<mask_type>(mask); } // }}}
std::size_t init_numa_node_number( std::size_t num_thread ) { // {{{ if (std::size_t(-1) == num_thread) return std::size_t(-1); UCHAR node_number = 0; if (GetNumaProcessorNode(UCHAR(num_thread), &node_number)) return node_number; std::size_t num_of_cores = hardware_concurrency(); if (0 == num_of_cores) num_of_cores = 1; // assume one core std::size_t num_of_numa_cores = num_of_cores; ULONG numa_nodes = 0; if (GetNumaHighestNodeNumber(&numa_nodes) && 0 != numa_nodes) num_of_numa_cores = num_of_cores / (numa_nodes + 1); return num_thread / num_of_numa_cores; } // }}}