@@ -317,6 +317,142 @@ struct disjoint_pool : public pool_interface<Provider> {
317
317
}
318
318
};
319
319
320
+ // benchmark tracking provider, by creating big number pools(2^7) stacked
321
+ template <typename Provider>
322
+ struct disjoint_pool_stack : public disjoint_pool <Provider> {
323
+ using base = disjoint_pool<Provider>;
324
+
325
+ std::vector<umf_memory_provider_handle_t > providers;
326
+ std::vector<umf_memory_pool_handle_t > pools;
327
+ std::vector<void *> pool_ptrs;
328
+
329
+ static constexpr size_t firstPoolSize = 2ull * 1024 * 1024 * 1024 ; // 2GB
330
+ static constexpr size_t levels = 7 ;
331
+
332
+ void SetUp (::benchmark::State &state) {
333
+ base::provider.SetUp (state);
334
+ if (state.thread_index () != 0 ) {
335
+ return ;
336
+ }
337
+
338
+ providers.push_back (base::provider.provider );
339
+ base::provider.provider = nullptr ;
340
+
341
+ auto params = base::getParams (state);
342
+ umf_memory_pool_handle_t rootPool = nullptr ;
343
+ auto umf_result = umfPoolCreate (base::getOps (state), providers[0 ],
344
+ params.get (), 0 , &rootPool);
345
+ if (umf_result != UMF_RESULT_SUCCESS) {
346
+ state.SkipWithError (" umfPoolCreate() failed" );
347
+ return ;
348
+ }
349
+
350
+ pools.push_back (rootPool); // root pool
351
+
352
+ umf_fixed_memory_provider_params_handle_t params_fixed = nullptr ;
353
+ umf_result = umfFixedMemoryProviderParamsCreate (
354
+ ¶ms_fixed, (void *)0x1 , 0x1 ); // dummy
355
+
356
+ size_t poolSize = firstPoolSize;
357
+ size_t level_start = 0 ;
358
+ size_t level_pools = 1 ;
359
+
360
+ for (size_t level = 1 ; level < levels; ++level) {
361
+ // split each pools for 3 parts - two for children, and third from other allocations from this pool
362
+ poolSize /= 3 ;
363
+ size_t new_level_pools = level_pools * 2 ;
364
+
365
+ for (size_t parent_idx = 0 ; parent_idx < level_pools;
366
+ ++parent_idx) {
367
+ umf_memory_pool_handle_t parent_pool =
368
+ pools[level_start + parent_idx];
369
+
370
+ for (int child = 0 ; child < 2 ; ++child) {
371
+ void *ptr = umfPoolMalloc (parent_pool, poolSize);
372
+ if (!ptr) {
373
+ state.SkipWithError (" umfPoolMalloc() failed" );
374
+ return ;
375
+ }
376
+ pool_ptrs.push_back (ptr);
377
+
378
+ umf_result = umfFixedMemoryProviderParamsSetMemory (
379
+ params_fixed, ptr, poolSize);
380
+ umf_memory_provider_handle_t prov;
381
+ umf_result = umfMemoryProviderCreate (
382
+ umfFixedMemoryProviderOps (), params_fixed, &prov);
383
+ if (umf_result != UMF_RESULT_SUCCESS) {
384
+ state.SkipWithError (" umfMemoryProviderCreate() failed" );
385
+ return ;
386
+ }
387
+ providers.push_back (prov);
388
+
389
+ umf_memory_pool_handle_t newPool;
390
+ umf_result = umfPoolCreate (base::getOps (state), prov,
391
+ params.get (), 0 , &newPool);
392
+ if (umf_result != UMF_RESULT_SUCCESS) {
393
+ state.SkipWithError (" umfPoolCreate() failed" );
394
+ return ;
395
+ }
396
+
397
+ pools.push_back (newPool);
398
+ }
399
+ }
400
+
401
+ level_start += level_pools;
402
+ level_pools = new_level_pools;
403
+ }
404
+
405
+ umfFixedMemoryProviderParamsDestroy (params_fixed);
406
+ }
407
+
408
+ void TearDown (::benchmark::State &state) {
409
+ if (state.thread_index () != 0 ) {
410
+ return ;
411
+ }
412
+
413
+ size_t pool_index = pools.size ();
414
+ size_t provider_index = providers.size ();
415
+ size_t ptr_index = pool_ptrs.size ();
416
+
417
+ // Go from last level to first (excluding level 0, root)
418
+ for (int level = levels - 1 ; level > 0 ; --level) {
419
+ size_t level_pools = 1ull << level; // 2^level pools
420
+
421
+ // Destroy pools
422
+ for (size_t i = 0 ; i < level_pools; ++i) {
423
+ --pool_index;
424
+ umfPoolDestroy (pools[pool_index]);
425
+ }
426
+
427
+ // Destroy providers and free pointers
428
+ for (size_t i = 0 ; i < level_pools; ++i) {
429
+ --provider_index;
430
+ umfMemoryProviderDestroy (providers[provider_index]);
431
+
432
+ --ptr_index;
433
+ void *ptr = pool_ptrs[ptr_index];
434
+ if (ptr) {
435
+ umfFree (ptr);
436
+ }
437
+ }
438
+ }
439
+
440
+ // Root pool and provider
441
+ umfPoolDestroy (pools[0 ]);
442
+ umfMemoryProviderDestroy (providers[0 ]);
443
+
444
+ pools.clear ();
445
+ providers.clear ();
446
+ pool_ptrs.clear ();
447
+
448
+ base::TearDown (state);
449
+ }
450
+
451
+ static std::string name () {
452
+ return " disjoint_pool_stacked<" + Provider::name () + " >" ;
453
+ }
454
+ };
455
+
320
456
#ifdef UMF_POOL_JEMALLOC_ENABLED
321
457
template <typename Provider>
322
458
struct jemalloc_pool : public pool_interface <Provider> {
0 commit comments