@@ -317,6 +317,142 @@ struct disjoint_pool : public pool_interface<Provider> {
317317 }
318318};
319319
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+
320456#ifdef UMF_POOL_JEMALLOC_ENABLED
321457template <typename Provider>
322458struct jemalloc_pool : public pool_interface <Provider> {
0 commit comments