Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use thread-safe cache in thread_local_caching_allocator #6539

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2023 Hartmut Kaiser
// Copyright (c) 2023-2024 Hartmut Kaiser
//
// SPDX-License-Identifier: BSL-1.0
// Distributed under the Boost Software License, Version 1.0. (See accompanying
Expand All @@ -12,7 +12,6 @@
#include <cstddef>
#include <memory>
#include <new>
#include <stack>
#include <type_traits>
#include <utility>

Expand All @@ -21,8 +20,10 @@ namespace hpx::util {
#if defined(HPX_ALLOCATOR_SUPPORT_HAVE_CACHING) && \
!((defined(HPX_HAVE_CUDA) && defined(__CUDACC__)) || \
defined(HPX_HAVE_HIP))

///////////////////////////////////////////////////////////////////////////
template <typename T = char, typename Allocator = std::allocator<T>>
template <template <typename, typename> class Stack, typename T = char,
typename Allocator = std::allocator<T>>
struct thread_local_caching_allocator
{
HPX_NO_UNIQUE_ADDRESS Allocator alloc;
Expand All @@ -38,7 +39,7 @@ namespace hpx::util {
template <typename U>
struct rebind
{
using other = thread_local_caching_allocator<U,
using other = thread_local_caching_allocator<Stack, U,
typename traits::template rebind_alloc<U>>;
};

Expand All @@ -56,6 +57,7 @@ namespace hpx::util {
explicit allocated_cache(Allocator const& a) noexcept(
noexcept(std::is_nothrow_copy_constructible_v<Allocator>))
: alloc(a)
, data(0)
{
}

Expand All @@ -72,19 +74,19 @@ namespace hpx::util {
pointer allocate(size_type n)
{
pointer p;
if (data.empty())
std::pair<T*, size_type> pair;
if (data.pop(pair))
{
p = pair.first;
}
else
{
p = traits::allocate(alloc, n);
if (p == nullptr)
{
throw std::bad_alloc();
}
}
else
{
p = data.top().first;
data.pop();
}

++allocated;
return p;
Expand All @@ -104,16 +106,15 @@ namespace hpx::util {
private:
void clear_cache() noexcept
{
while (!data.empty())
std::pair<T*, size_type> p;
while (data.pop(p))
{
traits::deallocate(
alloc, data.top().first, data.top().second);
data.pop();
traits::deallocate(alloc, p.first, p.second);
}
}

HPX_NO_UNIQUE_ADDRESS Allocator alloc;
std::stack<std::pair<T*, size_type>> data;
Stack<std::pair<T*, size_type>, Allocator> data;
std::size_t allocated = 0;
std::size_t deallocated = 0;
};
Expand All @@ -134,7 +135,7 @@ namespace hpx::util {

template <typename U, typename Alloc>
explicit thread_local_caching_allocator(
thread_local_caching_allocator<U, Alloc> const&
thread_local_caching_allocator<Stack, U, Alloc> const&
rhs) noexcept(noexcept(std::
is_nothrow_copy_constructible_v<Alloc>))
: alloc(rhs.alloc)
Expand Down Expand Up @@ -198,7 +199,8 @@ namespace hpx::util {
}
};
#else
template <typename T = char, typename Allocator = std::allocator<T>>
template <template <typename, typename> class Stack, typename T = char,
typename Allocator = std::allocator<T>>
using thread_local_caching_allocator = Allocator;
#endif
} // namespace hpx::util
4 changes: 2 additions & 2 deletions libs/core/async_base/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2020-2022 The STE||AR-Group
# Copyright (c) 2020-2024 The STE||AR-Group
#
# SPDX-License-Identifier: BSL-1.0
# Distributed under the Boost Software License, Version 1.0. (See accompanying
Expand Down Expand Up @@ -34,6 +34,6 @@ add_hpx_module(
COMPAT_HEADERS ${async_base_compat_headers}
SOURCES ${async_base_sources}
MODULE_DEPENDENCIES hpx_allocator_support hpx_concepts hpx_config
hpx_coroutines hpx_tag_invoke
hpx_concurrency hpx_coroutines hpx_tag_invoke
CMAKE_SUBDIRS examples tests
)
9 changes: 6 additions & 3 deletions libs/core/async_base/include/hpx/async_base/dataflow.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2007-2022 Hartmut Kaiser
// Copyright (c) 2007-2024 Hartmut Kaiser
//
// SPDX-License-Identifier: BSL-1.0
// Distributed under the Boost Software License, Version 1.0. (See accompanying
Expand Down Expand Up @@ -29,6 +29,7 @@ namespace hpx {
#else

#include <hpx/config.hpp>
#include <hpx/concurrency/stack.hpp>
#include <hpx/modules/allocator_support.hpp>
#include <hpx/modules/concepts.hpp>
#include <hpx/modules/tag_invoke.hpp>
Expand Down Expand Up @@ -60,12 +61,14 @@ namespace hpx {
// clang-format on
friend constexpr HPX_FORCEINLINE auto tag_fallback_invoke(
dataflow_t tag, F&& f, Ts&&... ts)
-> decltype(tag(hpx::util::thread_local_caching_allocator<char,
-> decltype(tag(hpx::util::thread_local_caching_allocator<
hpx::lockfree::variable_size_stack, char,
hpx::util::internal_allocator<>>{},
HPX_FORWARD(F, f), HPX_FORWARD(Ts, ts)...))
{
using allocator_type =
hpx::util::thread_local_caching_allocator<char,
hpx::util::thread_local_caching_allocator<
hpx::lockfree::variable_size_stack, char,
hpx::util::internal_allocator<>>;
return hpx::functional::tag_invoke(tag, allocator_type{},
HPX_FORWARD(F, f), HPX_FORWARD(Ts, ts)...);
Expand Down
3 changes: 2 additions & 1 deletion libs/core/async_combinators/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2019-2023 The STE||AR-Group
# Copyright (c) 2019-2024 The STE||AR-Group
#
# SPDX-License-Identifier: BSL-1.0
# Distributed under the Boost Software License, Version 1.0. (See accompanying
Expand Down Expand Up @@ -43,6 +43,7 @@ add_hpx_module(
EXCLUDE_FROM_GLOBAL_HEADER "hpx/async_combinators/future_wait.hpp"
MODULE_DEPENDENCIES
hpx_async_base
hpx_concurrency
hpx_config
hpx_errors
hpx_futures
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2007-2022 Hartmut Kaiser
// Copyright (c) 2007-2024 Hartmut Kaiser
// Copyright (c) 2013 Agustin Berge
// Copyright (c) 2017 Denis Blank
//
Expand Down Expand Up @@ -131,6 +131,7 @@ namespace hpx {
#include <hpx/config.hpp>
#include <hpx/allocator_support/internal_allocator.hpp>
#include <hpx/allocator_support/thread_local_caching_allocator.hpp>
#include <hpx/concurrency/stack.hpp>
#include <hpx/datastructures/tuple.hpp>
#include <hpx/functional/tag_invoke.hpp>
#include <hpx/futures/detail/future_data.hpp>
Expand Down Expand Up @@ -201,14 +202,16 @@ namespace hpx::lcos::detail {
return async_visit_future(HPX_FORWARD(T, current));
}

// clang-format off
template <typename T, typename N>
auto operator()(hpx::util::async_traverse_detach_tag, T&& current,
N&& next) -> decltype(async_detach_future(HPX_FORWARD(T, current),
HPX_FORWARD(N, next)))
HPX_FORWARD(N, next)))
{
return async_detach_future(
HPX_FORWARD(T, current), HPX_FORWARD(N, next));
}
// clang-format on

template <typename T>
void operator()(hpx::util::async_traverse_complete_tag, T&& pack)
Expand All @@ -226,7 +229,8 @@ namespace hpx::lcos::detail {
using frame_type = async_when_all_frame<result_type>;
using no_addref = typename frame_type::base_type::init_no_addref;

using allocator_type = hpx::util::thread_local_caching_allocator<char,
using allocator_type = hpx::util::thread_local_caching_allocator<
hpx::lockfree::variable_size_stack, char,
hpx::util::internal_allocator<>>;
auto frame = hpx::util::traverse_pack_async_allocator(allocator_type{},
hpx::util::async_traverse_in_place_tag<frame_type>{}, no_addref{},
Expand Down
8 changes: 7 additions & 1 deletion libs/core/concurrency/include/hpx/concurrency/stack.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 2008-2013 Tim Blechmann
// Copyright (c) 2022-2023 Hartmut Kaiser
// Copyright (c) 2022-2024 Hartmut Kaiser
//
// SPDX-License-Identifier: BSL-1.0
// Distributed under the Boost Software License, Version 1.0. (See accompanying
Expand Down Expand Up @@ -770,4 +770,10 @@ namespace hpx::lockfree {

pool_t pool;
};

template <typename T, typename Allocator = std::allocator<T>>
class variable_size_stack : public stack<T, Allocator>
{
using stack<T, Allocator>::stack;
};
} // namespace hpx::lockfree
8 changes: 4 additions & 4 deletions libs/core/concurrency/tests/unit/stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void ranged_unsynchronized_push_test()
HPX_TEST(!stk.unsynchronized_pop(out));
}

void fixed_size_stack_test()
void variable_size_stack_test()
{
hpx::lockfree::stack<long, std::allocator<long>, 128> stk;

Expand All @@ -89,7 +89,7 @@ void fixed_size_stack_test()
HPX_TEST(stk.empty());
}

void fixed_size_stack_test_exhausted()
void variable_size_stack_test_exhausted()
{
hpx::lockfree::stack<long, std::allocator<long>, 2> stk;

Expand Down Expand Up @@ -206,8 +206,8 @@ int main()
unsafe_stack_test();
ranged_push_test();
ranged_unsynchronized_push_test();
fixed_size_stack_test();
fixed_size_stack_test_exhausted();
variable_size_stack_test();
variable_size_stack_test_exhausted();
bounded_stack_test_exhausted();
stack_consume_one_test();
stack_consume_all_test();
Expand Down
3 changes: 2 additions & 1 deletion libs/core/execution/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2019-2022 The STE||AR-Group
# Copyright (c) 2019-2024 The STE||AR-Group
#
# SPDX-License-Identifier: BSL-1.0
# Distributed under the Boost Software License, Version 1.0. (See accompanying
Expand Down Expand Up @@ -160,6 +160,7 @@ add_hpx_module(
MODULE_DEPENDENCIES
hpx_async_base
hpx_async_combinators
hpx_concurrency
hpx_config
hpx_threading
hpx_pack_traversal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2007-2022 Hartmut Kaiser
// Copyright (c) 2007-2024 Hartmut Kaiser
// Copyright (c) 2013 Agustin Berge
//
// SPDX-License-Identifier: BSL-1.0
Expand All @@ -13,6 +13,7 @@
#include <hpx/assert.hpp>
#include <hpx/async_base/launch_policy.hpp>
#include <hpx/async_base/traits/is_launch_policy.hpp>
#include <hpx/concurrency/stack.hpp>
#include <hpx/coroutines/thread_enums.hpp>
#include <hpx/execution/traits/executor_traits.hpp>
#include <hpx/execution/traits/future_then_result_exec.hpp>
Expand Down Expand Up @@ -64,9 +65,9 @@ namespace hpx::lcos::detail {
using continuation_result_type =
hpx::util::invoke_result_t<F, Future>;

using allocator_type =
hpx::util::thread_local_caching_allocator<char,
hpx::util::internal_allocator<>>;
using allocator_type = hpx::util::thread_local_caching_allocator<
hpx::lockfree::variable_size_stack, char,
hpx::util::internal_allocator<>>;

hpx::traits::detail::shared_state_ptr_t<result_type> p =
detail::make_continuation_alloc<continuation_result_type>(
Expand Down
3 changes: 2 additions & 1 deletion libs/core/executors/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2020-2022 The STE||AR-Group
# Copyright (c) 2020-2024 The STE||AR-Group
#
# SPDX-License-Identifier: BSL-1.0
# Distributed under the Boost Software License, Version 1.0. (See accompanying
Expand Down Expand Up @@ -97,6 +97,7 @@ add_hpx_module(
hpx_allocator_support
hpx_async_base
hpx_concepts
hpx_concurrency
hpx_config
hpx_errors
hpx_execution
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2019-2020 ETH Zurich
// Copyright (c) 2007-2023 Hartmut Kaiser
// Copyright (c) 2007-2024 Hartmut Kaiser
// Copyright (c) 2019 Agustin Berge
//
// SPDX-License-Identifier: BSL-1.0
Expand All @@ -12,6 +12,7 @@
#include <hpx/allocator_support/internal_allocator.hpp>
#include <hpx/allocator_support/thread_local_caching_allocator.hpp>
#include <hpx/async_base/launch_policy.hpp>
#include <hpx/concurrency/stack.hpp>
#include <hpx/execution/detail/async_launch_policy_dispatch.hpp>
#include <hpx/execution/detail/future_exec.hpp>
#include <hpx/execution/detail/post_policy_dispatch.hpp>
Expand Down Expand Up @@ -389,9 +390,9 @@ namespace hpx::execution {
hpx::bind_back(HPX_FORWARD(F, f), HPX_FORWARD(Ts, ts)...));
#endif

using allocator_type =
hpx::util::thread_local_caching_allocator<char,
hpx::util::internal_allocator<>>;
using allocator_type = hpx::util::thread_local_caching_allocator<
hpx::lockfree::variable_size_stack, char,
hpx::util::internal_allocator<>>;
hpx::traits::detail::shared_state_ptr_t<result_type> p =
lcos::detail::make_continuation_alloc_nounwrap<result_type>(
allocator_type{}, HPX_FORWARD(Future, predecessor),
Expand Down
3 changes: 2 additions & 1 deletion libs/core/futures/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2019-2022 The STE||AR-Group
# Copyright (c) 2019-2024 The STE||AR-Group
#
# SPDX-License-Identifier: BSL-1.0
# Distributed under the Boost Software License, Version 1.0. (See accompanying
Expand Down Expand Up @@ -68,6 +68,7 @@ add_hpx_module(
hpx_assertion
hpx_async_base
hpx_concepts
hpx_concurrency
hpx_config
hpx_errors
hpx_functional
Expand Down
Loading
Loading