Skip to content

Commit fe7f879

Browse files
committed
make topology_init faster
1 parent a882507 commit fe7f879

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
@@ -35,7 +35,7 @@ static umf_result_t umfMemspaceHostAllCreate(umf_memspace_handle_t *hMemspace) {
3535

3636
umf_result_t umf_ret = UMF_RESULT_SUCCESS;
3737

38-
hwloc_topology_t topology = umfGetTopology();
38+
hwloc_topology_t topology = umfGetTopologyReduced();
3939
if (!topology) {
4040
// TODO: What would be an approrpiate err?
4141
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
@@ -24,6 +24,7 @@
2424
#include "ctl/ctl_internal.h"
2525
#include "libumf.h"
2626
#include "provider_os_memory_internal.h"
27+
#include "topology.h"
2728
#include "utils_assert.h"
2829
#include "utils_common.h"
2930
#include "utils_concurrency.h"
@@ -556,27 +557,19 @@ static umf_result_t os_initialize(const void *params, void **provider) {
556557

557558
memset(os_provider, 0, sizeof(*os_provider));
558559

559-
int r = hwloc_topology_init(&os_provider->topo);
560-
if (r) {
561-
LOG_ERR("HWLOC topology init failed");
562-
ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
563-
goto err_free_os_provider;
564-
}
565-
566-
r = hwloc_topology_load(os_provider->topo);
567-
if (r) {
560+
os_provider->topo = umfGetTopologyReduced();
561+
if (!os_provider->topo) {
568562
os_store_last_native_error(UMF_OS_RESULT_ERROR_TOPO_DISCOVERY_FAILED,
569563
0);
570564
LOG_ERR("HWLOC topology discovery failed");
571565
ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
572-
goto err_destroy_hwloc_topology;
573566
}
574567

575568
os_provider->fd_offset_map = critnib_new(NULL, NULL);
576569
if (!os_provider->fd_offset_map) {
577570
LOG_ERR("creating file descriptor offset map failed");
578571
ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
579-
goto err_destroy_hwloc_topology;
572+
goto err_free_os_provider;
580573
}
581574

582575
ret = translate_params(in_params, os_provider);
@@ -619,8 +612,6 @@ static umf_result_t os_initialize(const void *params, void **provider) {
619612
free_bitmaps(os_provider);
620613
err_destroy_critnib:
621614
critnib_delete(os_provider->fd_offset_map);
622-
err_destroy_hwloc_topology:
623-
hwloc_topology_destroy(os_provider->topo);
624615
err_free_os_provider:
625616
umf_ba_global_free(os_provider);
626617
return ret;
@@ -644,7 +635,7 @@ static umf_result_t os_finalize(void *provider) {
644635
if (os_provider->nodeset_str_buf) {
645636
umf_ba_global_free(os_provider->nodeset_str_buf);
646637
}
647-
hwloc_topology_destroy(os_provider->topo);
638+
648639
umf_ba_global_free(os_provider);
649640
return UMF_RESULT_SUCCESS;
650641
}

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_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)