Skip to content

Commit 9408362

Browse files
authored
Merge pull request #1469 from lplewa/hwloc_filter
make topology_init faster
2 parents e296e31 + 09e6cb0 commit 9408362

File tree

6 files changed

+56
-25
lines changed

6 files changed

+56
-25
lines changed

src/libumf.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,11 @@ umf_result_t umfInit(void) {
7474
if (TRACKER) {
7575
LOG_DEBUG("UMF library initialized");
7676
}
77-
77+
#if !defined(UMF_NO_HWLOC)
78+
// some benchmarks uses multiple forks, and topology initialization is very slow
79+
// so if we initialize topology before the first fork, we can get significant performance gain.
80+
umfGetTopologyReduced();
81+
#endif
7882
return UMF_RESULT_SUCCESS;
7983
}
8084

src/memspaces/memspace_host_all.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static umf_result_t umfMemspaceHostAllCreate(umf_memspace_handle_t *hMemspace) {
3737

3838
umf_result_t umf_ret = UMF_RESULT_SUCCESS;
3939

40-
hwloc_topology_t topology = umfGetTopology();
40+
hwloc_topology_t topology = umfGetTopologyReduced();
4141
if (!topology) {
4242
// TODO: What would be an approrpiate err?
4343
return UMF_RESULT_ERROR_UNKNOWN;

src/memtargets/memtarget_numa.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ static umf_result_t numa_get_capacity(void *memTarget, size_t *capacity) {
218218
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
219219
}
220220

221-
hwloc_topology_t topology = umfGetTopology();
221+
hwloc_topology_t topology = umfGetTopologyReduced();
222222
if (!topology) {
223223
return UMF_RESULT_ERROR_NOT_SUPPORTED;
224224
}

src/provider/provider_os_memory.c

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ umf_result_t umfOsMemoryProviderParamsSetPartitions(
9898
#include "critnib.h"
9999
#include "libumf.h"
100100
#include "provider_os_memory_internal.h"
101+
#include "topology.h"
101102
#include "utils_common.h"
102103
#include "utils_concurrency.h"
103104
#include "utils_log.h"
@@ -629,27 +630,19 @@ static umf_result_t os_initialize(const void *params, void **provider) {
629630

630631
memset(os_provider, 0, sizeof(*os_provider));
631632

632-
int r = hwloc_topology_init(&os_provider->topo);
633-
if (r) {
634-
LOG_ERR("HWLOC topology init failed");
635-
ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
636-
goto err_free_os_provider;
637-
}
638-
639-
r = hwloc_topology_load(os_provider->topo);
640-
if (r) {
633+
os_provider->topo = umfGetTopologyReduced();
634+
if (!os_provider->topo) {
641635
os_store_last_native_error(UMF_OS_RESULT_ERROR_TOPO_DISCOVERY_FAILED,
642636
0);
643637
LOG_ERR("HWLOC topology discovery failed");
644638
ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
645-
goto err_destroy_hwloc_topology;
646639
}
647640

648641
os_provider->fd_offset_map = critnib_new(NULL, NULL);
649642
if (!os_provider->fd_offset_map) {
650643
LOG_ERR("creating file descriptor offset map failed");
651644
ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
652-
goto err_destroy_hwloc_topology;
645+
goto err_free_os_provider;
653646
}
654647

655648
ret = translate_params(in_params, os_provider);
@@ -692,8 +685,6 @@ static umf_result_t os_initialize(const void *params, void **provider) {
692685
free_bitmaps(os_provider);
693686
err_destroy_critnib:
694687
critnib_delete(os_provider->fd_offset_map);
695-
err_destroy_hwloc_topology:
696-
hwloc_topology_destroy(os_provider->topo);
697688
err_free_os_provider:
698689
umf_ba_global_free(os_provider);
699690
return ret;
@@ -717,7 +708,7 @@ static umf_result_t os_finalize(void *provider) {
717708
if (os_provider->nodeset_str_buf) {
718709
umf_ba_global_free(os_provider->nodeset_str_buf);
719710
}
720-
hwloc_topology_destroy(os_provider->topo);
711+
721712
umf_ba_global_free(os_provider);
722713
return UMF_RESULT_SUCCESS;
723714
}

src/topology.c

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (C) 2024 Intel Corporation
3+
* Copyright (C) 2024-2025 Intel Corporation
44
*
55
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -13,7 +13,9 @@
1313
#include "utils_log.h"
1414

1515
static hwloc_topology_t topology = NULL;
16+
static hwloc_topology_t topology_reduced = NULL;
1617
static UTIL_ONCE_FLAG topology_initialized = UTIL_ONCE_FLAG_INIT;
18+
static UTIL_ONCE_FLAG topology_reduced_initialized = UTIL_ONCE_FLAG_INIT;
1719

1820
void umfDestroyTopology(void) {
1921
if (topology) {
@@ -24,22 +26,55 @@ void umfDestroyTopology(void) {
2426
memcpy(&topology_initialized, &is_initialized,
2527
sizeof(topology_initialized));
2628
}
29+
if (topology_reduced) {
30+
hwloc_topology_destroy(topology_reduced);
31+
32+
// portable version of "topology_initialized = UTIL_ONCE_FLAG_INIT;"
33+
static UTIL_ONCE_FLAG is_initialized = UTIL_ONCE_FLAG_INIT;
34+
memcpy(&topology_reduced_initialized, &is_initialized,
35+
sizeof(topology_reduced_initialized));
36+
}
2737
}
2838

29-
static void umfCreateTopology(void) {
30-
if (hwloc_topology_init(&topology)) {
39+
static void umfCreateTopologyHelper(bool reduced,
40+
hwloc_topology_t *topology_ptr) {
41+
if (hwloc_topology_init(topology_ptr)) {
3142
LOG_ERR("Failed to initialize topology");
32-
topology = NULL;
43+
*topology_ptr = NULL;
3344
return;
3445
}
3546

36-
if (hwloc_topology_load(topology)) {
47+
if (reduced) {
48+
// Set the topology to only include NUMA nodes and memory
49+
// to improve performance of the topology load on large systems
50+
if (hwloc_topology_set_all_types_filter(*topology_ptr,
51+
HWLOC_TYPE_FILTER_KEEP_NONE)) {
52+
LOG_ERR("Failed to set topology filter");
53+
hwloc_topology_destroy(*topology_ptr);
54+
*topology_ptr = NULL;
55+
return;
56+
}
57+
}
58+
if (hwloc_topology_load(*topology_ptr)) {
3759
LOG_ERR("Failed to initialize topology");
38-
hwloc_topology_destroy(topology);
39-
topology = NULL;
60+
hwloc_topology_destroy(*topology_ptr);
61+
*topology_ptr = NULL;
4062
}
4163
}
4264

65+
static void umfCreateTopology(void) {
66+
umfCreateTopologyHelper(false, &topology);
67+
}
68+
69+
static void umfCreateTopologyReduced(void) {
70+
umfCreateTopologyHelper(true, &topology_reduced);
71+
}
72+
73+
hwloc_topology_t umfGetTopologyReduced(void) {
74+
utils_init_once(&topology_reduced_initialized, umfCreateTopologyReduced);
75+
return topology_reduced;
76+
}
77+
4378
hwloc_topology_t umfGetTopology(void) {
4479
utils_init_once(&topology_initialized, umfCreateTopology);
4580
return topology;

src/topology.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (C) 2024 Intel Corporation
3+
* Copyright (C) 2024-2025 Intel Corporation
44
*
55
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -17,6 +17,7 @@ extern "C" {
1717
#endif
1818

1919
hwloc_topology_t umfGetTopology(void);
20+
hwloc_topology_t umfGetTopologyReduced(void);
2021
void umfDestroyTopology(void);
2122

2223
#ifdef __cplusplus

0 commit comments

Comments
 (0)