Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
kcenon::thread::numa_topology Class Reference

NUMA (Non-Uniform Memory Access) topology information. More...

#include <numa_topology.h>

Collaboration diagram for kcenon::thread::numa_topology:
Collaboration graph

Public Member Functions

 numa_topology ()=default
 Default constructor - creates an empty topology.
 
auto get_node_for_cpu (int cpu_id) const -> int
 Get the NUMA node for a given CPU.
 
auto get_distance (int node1, int node2) const -> int
 Get the distance between two NUMA nodes.
 
auto is_same_node (int cpu1, int cpu2) const -> bool
 Check if two CPUs are on the same NUMA node.
 
auto is_numa_available () const -> bool
 Check if NUMA is available on this system.
 
auto node_count () const -> std::size_t
 Get the number of NUMA nodes.
 
auto cpu_count () const -> std::size_t
 Get the total number of CPUs.
 
auto get_nodes () const -> const std::vector< numa_node > &
 Get all NUMA nodes.
 
auto get_cpus_for_node (int node_id) const -> std::vector< int >
 Get CPUs belonging to a specific node.
 

Static Public Member Functions

static auto detect () -> numa_topology
 Detect and return the system's NUMA topology.
 

Static Private Member Functions

static auto detect_linux () -> numa_topology
 Detect topology on Linux using sysfs.
 
static auto create_fallback () -> numa_topology
 Create fallback single-node topology.
 

Private Attributes

std::vector< numa_nodenodes_
 All NUMA nodes.
 
std::vector< int > cpu_to_node_
 CPU ID -> NUMA node mapping.
 
std::vector< std::vector< int > > distances_
 Inter-node distances.
 
std::size_t total_cpus_ {0}
 Total CPU count.
 

Detailed Description

NUMA (Non-Uniform Memory Access) topology information.

This class provides information about the system's NUMA topology, including the number of NUMA nodes, which CPUs belong to which nodes, and the distances between nodes.

Thread Safety

All methods are thread-safe after construction. The topology is detected once during construction and remains immutable.

Platform Support

  • Linux: Full support via /sys/devices/system/node
  • macOS: Falls back to single-node topology (no NUMA on macOS)
  • Windows: Falls back to single-node topology (could be extended)

Usage Example

auto topology = numa_topology::detect();
// Check if system has NUMA
if (topology.is_numa_available()) {
std::cout << "NUMA nodes: " << topology.node_count() << "\n";
// Find which node a CPU belongs to
int cpu_id = 0;
int node = topology.get_node_for_cpu(cpu_id);
// Check if two CPUs are on the same node
if (topology.is_same_node(0, 1)) {
std::cout << "CPU 0 and 1 are on the same NUMA node\n";
}
}
static auto detect() -> numa_topology
Detect and return the system's NUMA topology.

Definition at line 67 of file numa_topology.h.

Constructor & Destructor Documentation

◆ numa_topology()

kcenon::thread::numa_topology::numa_topology ( )
default

Default constructor - creates an empty topology.

Member Function Documentation

◆ cpu_count()

auto kcenon::thread::numa_topology::cpu_count ( ) const -> std::size_t
nodiscard

Get the total number of CPUs.

Returns
Total CPU count

Definition at line 81 of file numa_topology.cpp.

82{
83 return total_cpus_;
84}
std::size_t total_cpus_
Total CPU count.

References total_cpus_.

◆ create_fallback()

auto kcenon::thread::numa_topology::create_fallback ( ) -> numa_topology
staticprivate

Create fallback single-node topology.

Returns
Single-node topology with all CPUs

Definition at line 274 of file numa_topology.cpp.

275{
276 numa_topology topology;
277
278 unsigned int hw_concurrency = std::thread::hardware_concurrency();
279 if (hw_concurrency == 0)
280 {
281 hw_concurrency = 1;
282 }
283
284 // Create single NUMA node with all CPUs
285 numa_node node;
286 node.node_id = 0;
287 for (unsigned int i = 0; i < hw_concurrency; ++i)
288 {
289 node.cpu_ids.push_back(static_cast<int>(i));
290 }
291 node.memory_size_bytes = 0; // Unknown
292
293 topology.nodes_.push_back(std::move(node));
294 topology.total_cpus_ = hw_concurrency;
295
296 // Initialize cpu_to_node mapping
297 topology.cpu_to_node_.resize(hw_concurrency, 0);
298
299 // Single node has distance 10 to itself
300 topology.distances_ = {{10}};
301
302 return topology;
303}
numa_topology()=default
Default constructor - creates an empty topology.

References kcenon::thread::numa_node::cpu_ids, cpu_to_node_, distances_, kcenon::thread::numa_node::memory_size_bytes, kcenon::thread::numa_node::node_id, nodes_, and total_cpus_.

◆ detect()

auto kcenon::thread::numa_topology::detect ( ) -> numa_topology
staticnodiscard

Detect and return the system's NUMA topology.

Returns
numa_topology object with detected information

This static method detects the NUMA topology of the current system. On non-NUMA systems or unsupported platforms, it returns a single-node topology with all CPUs.

Definition at line 21 of file numa_topology.cpp.

22{
23#ifdef __linux__
24 return detect_linux();
25#else
26 // macOS, Windows, and other platforms: fallback to single-node topology
27 return create_fallback();
28#endif
29}
static auto detect_linux() -> numa_topology
Detect topology on Linux using sysfs.
static auto create_fallback() -> numa_topology
Create fallback single-node topology.

Referenced by kcenon::thread::numa_thread_pool::ensure_topology_detected().

Here is the caller graph for this function:

◆ detect_linux()

static auto kcenon::thread::numa_topology::detect_linux ( ) -> numa_topology
staticprivate

Detect topology on Linux using sysfs.

◆ get_cpus_for_node()

auto kcenon::thread::numa_topology::get_cpus_for_node ( int node_id) const -> std::vector<int>
nodiscard

Get CPUs belonging to a specific node.

Parameters
node_idNUMA node ID
Returns
Vector of CPU IDs, empty if node not found

Definition at line 91 of file numa_topology.cpp.

92{
93 for (const auto& node : nodes_)
94 {
95 if (node.node_id == node_id)
96 {
97 return node.cpu_ids;
98 }
99 }
100 return {};
101}
std::vector< numa_node > nodes_
All NUMA nodes.

◆ get_distance()

auto kcenon::thread::numa_topology::get_distance ( int node1,
int node2 ) const -> int
nodiscard

Get the distance between two NUMA nodes.

Parameters
node1First NUMA node ID
node2Second NUMA node ID
Returns
Distance value (10 = local, higher = farther), or -1 if invalid

The distance is a relative measure where:

  • 10 typically means local (same node)
  • Higher values indicate greater latency/bandwidth cost

Definition at line 40 of file numa_topology.cpp.

41{
42 if (node1 < 0 || node2 < 0 ||
43 static_cast<std::size_t>(node1) >= distances_.size() ||
44 static_cast<std::size_t>(node2) >= distances_.size())
45 {
46 return -1;
47 }
48
49 const auto& row = distances_[static_cast<std::size_t>(node1)];
50 if (static_cast<std::size_t>(node2) >= row.size())
51 {
52 return -1;
53 }
54
55 return row[static_cast<std::size_t>(node2)];
56}
std::vector< std::vector< int > > distances_
Inter-node distances.

◆ get_node_for_cpu()

auto kcenon::thread::numa_topology::get_node_for_cpu ( int cpu_id) const -> int
nodiscard

Get the NUMA node for a given CPU.

Parameters
cpu_idThe CPU identifier
Returns
NUMA node ID, or -1 if CPU not found

Definition at line 31 of file numa_topology.cpp.

32{
33 if (cpu_id < 0 || static_cast<std::size_t>(cpu_id) >= cpu_to_node_.size())
34 {
35 return -1;
36 }
37 return cpu_to_node_[static_cast<std::size_t>(cpu_id)];
38}
std::vector< int > cpu_to_node_
CPU ID -> NUMA node mapping.

◆ get_nodes()

auto kcenon::thread::numa_topology::get_nodes ( ) const -> const std::vector<numa_node>&
nodiscard

Get all NUMA nodes.

Returns
Vector of numa_node structures

Definition at line 86 of file numa_topology.cpp.

87{
88 return nodes_;
89}

References nodes_.

◆ is_numa_available()

auto kcenon::thread::numa_topology::is_numa_available ( ) const -> bool
nodiscard

Check if NUMA is available on this system.

Returns
true if system has multiple NUMA nodes

Definition at line 71 of file numa_topology.cpp.

72{
73 return nodes_.size() > 1;
74}

References nodes_.

Referenced by kcenon::thread::numa_thread_pool::is_numa_system().

Here is the caller graph for this function:

◆ is_same_node()

auto kcenon::thread::numa_topology::is_same_node ( int cpu1,
int cpu2 ) const -> bool
nodiscard

Check if two CPUs are on the same NUMA node.

Parameters
cpu1First CPU ID
cpu2Second CPU ID
Returns
true if both CPUs are on the same node

Definition at line 58 of file numa_topology.cpp.

59{
60 int node1 = get_node_for_cpu(cpu1);
61 int node2 = get_node_for_cpu(cpu2);
62
63 if (node1 < 0 || node2 < 0)
64 {
65 return false;
66 }
67
68 return node1 == node2;
69}
auto get_node_for_cpu(int cpu_id) const -> int
Get the NUMA node for a given CPU.

◆ node_count()

auto kcenon::thread::numa_topology::node_count ( ) const -> std::size_t
nodiscard

Get the number of NUMA nodes.

Returns
Number of NUMA nodes

Definition at line 76 of file numa_topology.cpp.

77{
78 return nodes_.size();
79}

References nodes_.

Referenced by kcenon::thread::numa_thread_pool::configure_numa_work_stealing().

Here is the caller graph for this function:

Member Data Documentation

◆ cpu_to_node_

std::vector<int> kcenon::thread::numa_topology::cpu_to_node_
private

CPU ID -> NUMA node mapping.

Definition at line 145 of file numa_topology.h.

Referenced by create_fallback().

◆ distances_

std::vector<std::vector<int> > kcenon::thread::numa_topology::distances_
private

Inter-node distances.

Definition at line 146 of file numa_topology.h.

Referenced by create_fallback().

◆ nodes_

std::vector<numa_node> kcenon::thread::numa_topology::nodes_
private

All NUMA nodes.

Definition at line 144 of file numa_topology.h.

Referenced by create_fallback(), get_nodes(), is_numa_available(), and node_count().

◆ total_cpus_

std::size_t kcenon::thread::numa_topology::total_cpus_ {0}
private

Total CPU count.

Definition at line 147 of file numa_topology.h.

147{0};

Referenced by cpu_count(), and create_fallback().


The documentation for this class was generated from the following files: