Skip to content

Commit 0bcc7f7

Browse files
committed
use the provider's GetCachelineSize() to calculate bucket sizes in DP
1 parent fcd626e commit 0bcc7f7

5 files changed

Lines changed: 49 additions & 21 deletions

File tree

include/umf/pools/pool_disjoint.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (C) 2023-2025 Intel Corporation
3+
* Copyright (C) 2023-2026 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
@@ -82,7 +82,7 @@ umfDisjointPoolParamsSetCapacity(umf_disjoint_pool_params_handle_t hParams,
8282
size_t maxCapacity);
8383

8484
/// @brief Set minimum bucket allocation size.
85-
/// @details Default value for minimum bucket size is 8.
85+
/// @details If not set, the pool uses the provider cache line size.
8686
/// @param hParams handle to the parameters of the disjoint pool.
8787
/// @param minBucketSize minimum bucket size. Must be power of 2.
8888
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.

src/pool/pool_disjoint.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2022-2025 Intel Corporation
2+
* Copyright (C) 2022-2026 Intel Corporation
33
*
44
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
55
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -1120,6 +1120,7 @@ static const umf_disjoint_pool_params_t default_params = {
11201120
.max_poolable_size = 2 * 1024 * 1024, // 2MB default
11211121
.capacity = 4, // default
11221122
.min_bucket_size = 8, // default
1123+
.min_bucket_size_set = false,
11231124
.cur_pool_size = 0,
11241125
.pool_trace = 0,
11251126
.shared_limits = NULL,
@@ -1191,6 +1192,15 @@ umf_result_t disjoint_pool_post_initialize(void *ppPool) {
11911192
goto err_free_disjoint_pool;
11921193
}
11931194

1195+
if (!disjoint_pool->params.min_bucket_size_set) {
1196+
size_t cache_line_size;
1197+
umf_result_t ret = umfMemoryProviderGetCacheLineSize(
1198+
disjoint_pool->provider, &cache_line_size);
1199+
if (ret == UMF_RESULT_SUCCESS) {
1200+
disjoint_pool->params.min_bucket_size = cache_line_size;
1201+
}
1202+
}
1203+
11941204
// Generate buckets sized such as: 64, 96, 128, 192, ..., CutOff.
11951205
// Powers of 2 and the value halfway between the powers of 2.
11961206
size_t Size1 = disjoint_pool->params.min_bucket_size;
@@ -1201,6 +1211,11 @@ umf_result_t disjoint_pool_post_initialize(void *ppPool) {
12011211
// Buckets sized smaller than the bucket default size- 8 aren't needed.
12021212
Size1 = utils_max(Size1, UMF_DISJOINT_POOL_MIN_BUCKET_DEFAULT_SIZE);
12031213

1214+
// Calculate the size of the "halfway" bucket, round it up to the next
1215+
// multiple of min_bucket_size.
1216+
size_t Size2 = Size1 + Size1 / 2;
1217+
Size2 = ALIGN_UP_SAFE(Size2, disjoint_pool->params.min_bucket_size);
1218+
12041219
// Calculate the exponent for min_bucket_size used for finding buckets.
12051220
disjoint_pool->min_bucket_size_exp = (size_t)utils_msb64(Size1);
12061221
if (umfDisjointPoolSharedLimitsCreate(
@@ -1211,11 +1226,10 @@ umf_result_t disjoint_pool_post_initialize(void *ppPool) {
12111226

12121227
// count number of buckets, start from 1
12131228
disjoint_pool->buckets_num = 1;
1214-
size_t Size2 = Size1 + Size1 / 2;
1215-
size_t ts2 = Size2, ts1 = Size1;
1216-
while (Size2 < CutOff) {
1229+
size_t ts2 = Size2;
1230+
while (ts2 < CutOff) {
12171231
disjoint_pool->buckets_num += 2;
1218-
Size2 *= 2;
1232+
ts2 *= 2;
12191233
}
12201234

12211235
disjoint_pool->buckets = umf_ba_global_alloc(
@@ -1225,8 +1239,6 @@ umf_result_t disjoint_pool_post_initialize(void *ppPool) {
12251239
}
12261240

12271241
size_t i = 0;
1228-
Size1 = ts1;
1229-
Size2 = ts2;
12301242
for (; Size2 < CutOff; Size1 *= 2, Size2 *= 2, i += 2) {
12311243
disjoint_pool->buckets[i] = create_bucket(
12321244
Size1, disjoint_pool, disjoint_pool_get_limits(disjoint_pool));
@@ -1733,6 +1745,7 @@ umfDisjointPoolParamsSetMinBucketSize(umf_disjoint_pool_params_handle_t hParams,
17331745
}
17341746

17351747
hParams->min_bucket_size = minBucketSize;
1748+
hParams->min_bucket_size_set = true;
17361749
return UMF_RESULT_SUCCESS;
17371750
}
17381751

src/pool/pool_disjoint_internal.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2025 Intel Corporation
2+
* Copyright (C) 2025-2026 Intel Corporation
33
*
44
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
55
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -120,7 +120,8 @@ typedef struct umf_disjoint_pool_params_t {
120120

121121
// Holds the minimum bucket size valid for allocation of a memory type.
122122
// This value must be a power of 2.
123-
size_t min_bucket_size; // Default: 8
123+
size_t min_bucket_size; // Default: provider cache line size
124+
bool min_bucket_size_set;
124125

125126
// Holds size of the pool managed by the allocator.
126127
size_t cur_pool_size; // Default: 0

test/pools/disjoint_pool.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2023-2025 Intel Corporation
1+
// Copyright (C) 2023-2026 Intel Corporation
22
// Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
33
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44

@@ -44,6 +44,11 @@ TEST_F(test, internals) {
4444
*pageSize = 1024;
4545
return UMF_RESULT_SUCCESS;
4646
}
47+
48+
umf_result_t get_cache_line_size(size_t *size) noexcept {
49+
*size = 128;
50+
return UMF_RESULT_SUCCESS;
51+
}
4752
};
4853
umf_memory_provider_ops_t provider_ops =
4954
umf_test::providerMakeCOps<memory_provider, void>();
@@ -78,7 +83,8 @@ TEST_F(test, internals) {
7883
EXPECT_EQ(pool->provider_min_page_size, (size_t)1024);
7984

8085
// check buckets sizes
81-
size_t expected_size = DEFAULT_DISJOINT_MIN_BUCKET_SIZE;
86+
size_t expected_size = params->min_bucket_size;
87+
8288
EXPECT_EQ(pool->buckets[0]->size, expected_size);
8389
EXPECT_EQ(pool->buckets[pool->buckets_num - 1]->size,
8490
(size_t)1 << 31); // 2GB
@@ -87,12 +93,11 @@ TEST_F(test, internals) {
8793
EXPECT_NE(bucket, nullptr);
8894
EXPECT_EQ(bucket->size, expected_size);
8995

90-
// assuming DEFAULT_DISJOINT_MIN_BUCKET_SIZE = 64, expected bucket
91-
// sizes are: 64, 96, 128, 192, 256, ..., 2GB
96+
// expected bucket sizes are: min, 1.5*min, 2*min, ..., 2GB
9297
if (i % 2 == 0) {
9398
expected_size += expected_size / 2;
9499
} else {
95-
expected_size = DEFAULT_DISJOINT_MIN_BUCKET_SIZE << ((i + 1) / 2);
100+
expected_size = params->min_bucket_size << ((i + 1) / 2);
96101
}
97102
}
98103

test/pools/disjoint_pool_ctl.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2025 Intel Corporation
1+
// Copyright (C) 2025-2026 Intel Corporation
22
// Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
33
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exceptiongi
44

@@ -614,10 +614,19 @@ TEST_F(test, disjointCtlBucketStats) {
614614
sizeof(count), poolWrapper.get()));
615615
EXPECT_GE(count, 0ull);
616616

617-
auto expected_bucket_size = [](size_t i) -> size_t {
618-
// Even indexes: 8 << (i/2) => 8,16,32,64,...
619-
// Odd indexes: 12 << (i/2) => 12,24,48,96,...
620-
return (i % 2 == 0) ? (size_t(8) << (i / 2)) : (size_t(12) << (i / 2));
617+
size_t min_bucket_size = 0;
618+
ASSERT_SUCCESS(umfCtlGet("umf.pool.by_handle.{}.params.min_bucket_size",
619+
&min_bucket_size, sizeof(min_bucket_size),
620+
poolWrapper.get()));
621+
622+
auto expected_bucket_size = [min_bucket_size](size_t i) -> size_t {
623+
// Even indexes: min,2*min,4*min,...
624+
// Odd indexes: 1.5*min,3*min,6*min,...
625+
// NOTE: all sizes need to be rounded up to the nearest multiple of min_bucket_size
626+
size_t size =
627+
(i % 2 == 0) ? (min_bucket_size << (i / 2))
628+
: ((min_bucket_size + min_bucket_size / 2) << (i / 2));
629+
return ALIGN_UP_SAFE(size, min_bucket_size);
621630
};
622631

623632
for (size_t i = 0; i < count; i++) {

0 commit comments

Comments
 (0)