Skip to content

Commit fafd1ac

Browse files
committed
make topology_init faster
1 parent 1de269c commit fafd1ac

File tree

6 files changed

+59
-24
lines changed

6 files changed

+59
-24
lines changed

src/libumf.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ umf_result_t umfInit(void) {
7575
LOG_DEBUG("UMF library initialized");
7676
}
7777

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();
7881
return UMF_RESULT_SUCCESS;
7982
}
8083

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: 47 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,60 @@ 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
}
46+
if (reduced) {
47+
if (hwloc_topology_set_all_types_filter(*topology_ptr,
48+
HWLOC_TYPE_FILTER_KEEP_NONE)) {
49+
LOG_ERR("Failed to set topology filter");
50+
hwloc_topology_destroy(*topology_ptr);
51+
*topology_ptr = NULL;
52+
return;
53+
}
3554

36-
if (hwloc_topology_load(topology)) {
55+
if (hwloc_topology_set_type_filter(*topology_ptr, HWLOC_OBJ_CORE,
56+
HWLOC_TYPE_FILTER_KEEP_ALL)) {
57+
LOG_ERR("Failed to set core filter");
58+
hwloc_topology_destroy(*topology_ptr);
59+
*topology_ptr = NULL;
60+
return;
61+
}
62+
}
63+
if (hwloc_topology_load(*topology_ptr)) {
3764
LOG_ERR("Failed to initialize topology");
38-
hwloc_topology_destroy(topology);
39-
topology = NULL;
65+
hwloc_topology_destroy(*topology_ptr);
66+
*topology_ptr = NULL;
4067
}
4168
}
4269

70+
static void umfCreateTopology(void) {
71+
umfCreateTopologyHelper(false, &topology);
72+
}
73+
74+
static void umfCreateTopologyReduced(void) {
75+
umfCreateTopologyHelper(true, &topology_reduced);
76+
}
77+
78+
hwloc_topology_t umfGetTopologyReduced(void) {
79+
utils_init_once(&topology_reduced_initialized, umfCreateTopologyReduced);
80+
return topology_reduced;
81+
}
82+
4383
hwloc_topology_t umfGetTopology(void) {
4484
utils_init_once(&topology_initialized, umfCreateTopology);
4585
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)