aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeandro Pereira <leandro@hardinfo.org>2021-02-21 12:02:23 -0800
committerLeandro Pereira <leandro@hardinfo.org>2021-02-21 12:05:43 -0800
commit903e85283e33fedb639ba93f9d152eddb3ebfa78 (patch)
tree29d09d5d745c7d684e40d94f9d8616f32ccfebe6
parentd5a97bb0e19fdac034246f7277410b7ec86231e0 (diff)
Add support for NUMA nodes
Related to #599.
-rw-r--r--hardinfo/cpu_util.c71
-rw-r--r--includes/cpu_util.h2
-rw-r--r--modules/benchmark.c15
-rw-r--r--modules/benchmark/bench_results.c9
-rw-r--r--modules/benchmark/sysbench.c6
-rw-r--r--modules/devices.c11
6 files changed, 75 insertions, 39 deletions
diff --git a/hardinfo/cpu_util.c b/hardinfo/cpu_util.c
index 5064c173..60f2bbae 100644
--- a/hardinfo/cpu_util.c
+++ b/hardinfo/cpu_util.c
@@ -71,37 +71,58 @@ gint get_cpu_int(const char* item, int cpuid, int null_val) {
#define MAX_CORES_PER_PACK 256
#define MAX_PACKS 128
-int cpu_procs_cores_threads(int *p, int *c, int *t) {
+int cpu_procs_cores_threads_nodes(int *p, int *c, int *t, int *n)
+{
cpubits *threads, *cores, *packs;
char *tmp;
int i, m, pack_id, core_id;
+
g_file_get_contents("/sys/devices/system/cpu/present", &tmp, NULL, NULL);
- if (tmp != NULL) {
- threads = cpubits_from_str(tmp);
- cores = cpubits_from_str("");
- packs = cpubits_from_str("");
- m = cpubits_max(threads);
- for (i = 0; i <= m; i++) {
- pack_id = get_cpu_int("topology/physical_package_id", i, CPU_TOPO_NULL);
- core_id = get_cpu_int("topology/core_id", i, CPU_TOPO_NULL);
- if (pack_id < 0) pack_id = 0;
- CPUBIT_SET(packs, pack_id);
- if (core_id >= 0) { CPUBIT_SET(cores, (pack_id * MAX_CORES_PER_PACK) + core_id ); }
- }
- *t = cpubits_count(threads);
- *c = cpubits_count(cores);
- *p = cpubits_count(packs);
- if (!*c) *c = 1;
- if (!*p) *p = 1;
- free(threads);
- free(cores);
- free(packs);
- free(tmp);
- return 1;
- } else {
- *p = *c = *t = -1;
+ if (tmp == NULL) {
+ *p = *c = *t = *n = -1;
return 0;
}
+
+ threads = cpubits_from_str(tmp);
+ cores = cpubits_from_str("");
+ packs = cpubits_from_str("");
+ m = cpubits_max(threads);
+ for (i = 0; i <= m; i++) {
+ pack_id = get_cpu_int("topology/physical_package_id", i, CPU_TOPO_NULL);
+ core_id = get_cpu_int("topology/core_id", i, CPU_TOPO_NULL);
+ if (pack_id < 0)
+ pack_id = 0;
+ CPUBIT_SET(packs, pack_id);
+ if (core_id >= 0) {
+ CPUBIT_SET(cores, (pack_id * MAX_CORES_PER_PACK) + core_id);
+ }
+ }
+
+ *t = cpubits_count(threads);
+ *c = cpubits_count(cores);
+ *p = cpubits_count(packs);
+
+ g_free(tmp);
+ g_file_get_contents("/sys/devices/system/node/possible", &tmp, NULL, NULL);
+ if (tmp != NULL) {
+ cpubits *nodes = cpubits_from_str(tmp);
+ if (nodes)
+ *n = cpubits_count(nodes);
+ free(nodes);
+ }
+
+ if (!*c)
+ *c = 1;
+ if (!*p)
+ *p = 1;
+ if (!*n)
+ *n = 1;
+
+ g_free(threads);
+ g_free(cores);
+ g_free(packs);
+ g_free(tmp);
+ return 1;
}
cpufreq_data *cpufreq_new(gint id)
diff --git a/includes/cpu_util.h b/includes/cpu_util.h
index c11d3f69..1adbf491 100644
--- a/includes/cpu_util.h
+++ b/includes/cpu_util.h
@@ -47,4 +47,6 @@ void cputopo_free(cpu_topology_data *cputd);
gchar *cputopo_section_str(cpu_topology_data *cputd);
+int cpu_procs_cores_threads_nodes(int *p, int *c, int *t, int *n);
+
#endif
diff --git a/modules/benchmark.c b/modules/benchmark.c
index 6d36100f..4b536d42 100644
--- a/modules/benchmark.c
+++ b/modules/benchmark.c
@@ -135,14 +135,15 @@ bench_value benchmark_crunch_for(float seconds,
gpointer callback,
gpointer callback_data)
{
- int cpu_procs, cpu_cores, cpu_threads, thread_number, stop = 0;
+ int cpu_procs, cpu_cores, cpu_threads, cpu_nodes;
+ int thread_number, stop = 0;
GSList *threads = NULL, *t;
GTimer *timer;
bench_value ret = EMPTY_BENCH_VALUE;
timer = g_timer_new();
- cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads);
+ cpu_procs_cores_threads_nodes(&cpu_procs, &cpu_cores, &cpu_threads, &cpu_nodes);
if (n_threads > 0)
ret.threads_used = n_threads;
else if (n_threads < 0)
@@ -222,12 +223,14 @@ static gpointer benchmark_parallel_for_dispatcher(gpointer data)
bench_value
benchmark_parallel(gint n_threads, gpointer callback, gpointer callback_data)
{
- int cpu_procs, cpu_cores, cpu_threads;
- cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads);
+ int cpu_procs, cpu_cores, cpu_threads, cpu_nodes;
+ cpu_procs_cores_threads_nodes(&cpu_procs, &cpu_cores, &cpu_threads, &cpu_nodes);
+
if (n_threads == 0)
n_threads = cpu_threads;
else if (n_threads == -1)
n_threads = cpu_cores;
+
return benchmark_parallel_for(n_threads, 0, n_threads, callback,
callback_data);
}
@@ -244,7 +247,7 @@ bench_value benchmark_parallel_for(gint n_threads,
gpointer callback_data)
{
gchar *temp;
- int cpu_procs, cpu_cores, cpu_threads;
+ int cpu_procs, cpu_cores, cpu_threads, cpu_nodes;
guint iter_per_thread, iter, thread_number = 0;
GSList *threads = NULL, *t;
GTimer *timer;
@@ -253,7 +256,7 @@ bench_value benchmark_parallel_for(gint n_threads,
timer = g_timer_new();
- cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads);
+ cpu_procs_cores_threads_nodes(&cpu_procs, &cpu_cores, &cpu_threads, &cpu_nodes);
if (n_threads > 0)
ret.threads_used = n_threads;
diff --git a/modules/benchmark/bench_results.c b/modules/benchmark/bench_results.c
index 40345aa5..6ba475ed 100644
--- a/modules/benchmark/bench_results.c
+++ b/modules/benchmark/bench_results.c
@@ -40,6 +40,7 @@ typedef struct {
int processors;
int cores;
int threads;
+ int nodes;
char *mid;
int ptr_bits; /* 32, 64... BENCH_PTR_BITS; 0 for unspecified */
int is_su_data; /* 1 = data collected as root */
@@ -183,7 +184,7 @@ bench_machine *bench_machine_this()
m->machine_type = module_call_method("computer::getMachineType");
free(tmp);
- cpu_procs_cores_threads(&m->processors, &m->cores, &m->threads);
+ cpu_procs_cores_threads_nodes(&m->processors, &m->cores, &m->threads, &m->nodes);
gen_machine_id(m);
}
return m;
@@ -355,6 +356,11 @@ bench_result *bench_result_benchmarkjson(const gchar *bench_name,
json_get_string(machine, "UserNote"));
filter_invalid_chars(b->bvalue.user_note);
+ int nodes = json_get_int(machine, "NumNodes");
+
+ if (nodes == 0)
+ nodes = 1;
+
b->machine = bench_machine_new();
*b->machine = (bench_machine){
.board = json_get_string_dup(machine, "Board"),
@@ -367,6 +373,7 @@ bench_result *bench_result_benchmarkjson(const gchar *bench_name,
.processors = json_get_int(machine, "NumCpus"),
.cores = json_get_int(machine, "NumCores"),
.threads = json_get_int(machine, "NumThreads"),
+ .nodes = nodes,
.mid = json_get_string_dup(machine, "MachineId"),
.ptr_bits = json_get_int(machine, "PointerBits"),
.is_su_data = json_get_boolean(machine, "DataFromSuperUser"),
diff --git a/modules/benchmark/sysbench.c b/modules/benchmark/sysbench.c
index 9b8a4a38..75008804 100644
--- a/modules/benchmark/sysbench.c
+++ b/modules/benchmark/sysbench.c
@@ -230,8 +230,10 @@ void benchmark_sbcpu_single(void) {
}
void benchmark_sbcpu_all(void) {
- int cpu_procs, cpu_cores, cpu_threads;
- cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads);
+ int cpu_procs, cpu_cores, cpu_threads, cpu_nodes;
+
+ cpu_procs_cores_threads_nodes(&cpu_procs, &cpu_cores, &cpu_threads, &cpu_nodes);
+
struct sysbench_ctx ctx = {
.test = "cpu",
.threads = cpu_threads,
diff --git a/modules/devices.c b/modules/devices.c
index 578cce3f..d6f30aef 100644
--- a/modules/devices.c
+++ b/modules/devices.c
@@ -166,19 +166,20 @@ static gint proc_cmp_max_freq(Processor *a, Processor *b) {
gchar *processor_describe_default(GSList * processors)
{
- int packs, cores, threads;
- const gchar *packs_fmt, *cores_fmt, *threads_fmt;
+ int packs, cores, threads, nodes;
+ const gchar *packs_fmt, *cores_fmt, *threads_fmt, *nodes_fmt;
gchar *ret, *full_fmt;
- cpu_procs_cores_threads(&packs, &cores, &threads);
+ cpu_procs_cores_threads_nodes(&packs, &cores, &threads, &nodes);
/* if topology info was available, else fallback to old method */
if (cores > 0) {
packs_fmt = ngettext("%d physical processor", "%d physical processors", packs);
cores_fmt = ngettext("%d core", "%d cores", cores);
threads_fmt = ngettext("%d thread", "%d threads", threads);
- full_fmt = g_strdup_printf(_(/*/NP procs; NC cores; NT threads*/ "%s; %s; %s"), packs_fmt, cores_fmt, threads_fmt);
- ret = g_strdup_printf(full_fmt, packs, cores, threads);
+ nodes_fmt = ngettext("%d NUMA node", "%d NUMA nodes", nodes);
+ full_fmt = g_strdup_printf(_(/*/NP procs; NC cores; NN nodes; NT threads*/ "%s; %s, %s; %s"), packs_fmt, cores_fmt, nodes_fmt, threads_fmt);
+ ret = g_strdup_printf(full_fmt, packs, cores, nodes, threads);
g_free(full_fmt);
return ret;
} else {