Skip to content

Commit

Permalink
Add single thread allocation mode (experimental).
Browse files Browse the repository at this point in the history
  • Loading branch information
KIwabuchi committed Oct 9, 2023
1 parent 4f74811 commit 47dea96
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ set(INITIAL_SEGMENT_SIZE "0" CACHE STRING
"Set the initial segment size (use the internally defined value if 0 is specified)")

# ---------- Experimental options ---------- #
# This mode still uses multiple threads inside Metall.
# However, applications must not use metall with multiple threads.
option(SINGLE_THREAD_ALLOC "Optimize Metall kernel for single thread usage" OFF)

option(USE_ANONYMOUS_NEW_MAP "Use the anonymous map when creating a new map region" OFF)
set(UMAP_ROOT "" CACHE PATH "UMap installed root directory")

Expand Down Expand Up @@ -211,6 +215,11 @@ if (USE_ANONYMOUS_NEW_MAP)
message(STATUS "Use the anonymous map for new map region")
endif ()

if (SINGLE_THREAD_ALLOC)
list(APPEND METALL_DEFS "METALL_SINGLE_THREAD_ALLOC")
message(STATUS "Optimize Metall kernel for single thread usage")
endif ()

# Requirements for GCC
if (NOT RUN_BUILD_AND_TEST_WITH_CI)
if (("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU"))
Expand Down
36 changes: 27 additions & 9 deletions include/metall/kernel/object_cache.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019 Lawrence Livermore National Security, LLC and other Metall
// Copyright 2023 Lawrence Livermore National Security, LLC and other Metall
// Project Developers. See the top-level COPYRIGHT file for details.
//
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
Expand All @@ -19,10 +19,13 @@
#include <metall/kernel/object_cache_container.hpp>
#include <metall/detail/proc.hpp>
#include <metall/detail/hash.hpp>
#define ENABLE_MUTEX_IN_METALL_OBJECT_CACHE 1
#if ENABLE_MUTEX_IN_METALL_OBJECT_CACHE

#ifndef METALL_SINGLE_THREAD_ALLOC
#define METALL_ENABLE_MUTEX_IN_OBJECT_CACHE
#ifdef METALL_ENABLE_MUTEX_IN_OBJECT_CACHE
#include <metall/detail/mutex.hpp>
#endif
#endif

namespace metall::kernel {

Expand Down Expand Up @@ -54,7 +57,12 @@ class object_cache {
// Private types and static values
// -------------------- //

static constexpr std::size_t k_num_cache_per_core = 4;
static constexpr std::size_t k_num_cache_per_core =
#ifdef METALL_SINGLE_THREAD_ALLOC
1;
#else
4;
#endif
static constexpr std::size_t k_cache_bin_size = 1ULL << 20ULL;
static constexpr std::size_t k_max_cache_block_size =
64; // Add and remove caches by up to this size
Expand All @@ -69,7 +77,7 @@ class object_cache {
difference_type, bin_no_manager>;
using cache_table_type = std::vector<single_cache_type>;

#if ENABLE_MUTEX_IN_METALL_OBJECT_CACHE
#ifdef METALL_ENABLE_MUTEX_IN_OBJECT_CACHE
using mutex_type = mdtl::mutex;
using lock_guard_type = mdtl::mutex_lock_guard;
#endif
Expand All @@ -85,7 +93,7 @@ class object_cache {
// -------------------- //
object_cache()
: m_cache_table(get_num_cores() * k_num_cache_per_core)
#if ENABLE_MUTEX_IN_METALL_OBJECT_CACHE
#ifdef METALL_ENABLE_MUTEX_IN_OBJECT_CACHE
,
m_mutex(m_cache_table.size())
#endif
Expand All @@ -112,7 +120,7 @@ class object_cache {
if (bin_no > max_bin_no()) return -1;

const auto cache_no = priv_comp_cache_no();
#if ENABLE_MUTEX_IN_METALL_OBJECT_CACHE
#ifdef METALL_ENABLE_MUTEX_IN_OBJECT_CACHE
lock_guard_type guard(m_mutex[cache_no]);
#endif
if (m_cache_table[cache_no].empty(bin_no)) {
Expand Down Expand Up @@ -140,7 +148,7 @@ class object_cache {
if (bin_no > max_bin_no()) return false; // Error

const auto cache_no = priv_comp_cache_no();
#if ENABLE_MUTEX_IN_METALL_OBJECT_CACHE
#ifdef METALL_ENABLE_MUTEX_IN_OBJECT_CACHE
lock_guard_type guard(m_mutex[cache_no]);
#endif
m_cache_table[cache_no].push(bin_no, object_offset);
Expand Down Expand Up @@ -224,6 +232,9 @@ class object_cache {
}

std::size_t priv_comp_cache_no() const {
#ifdef METALL_SINGLE_THREAD_ALLOC
return 0;
#endif
#if SUPPORT_GET_CPU_CORE_NO
thread_local static const auto sub_cache_no =
std::hash<std::thread::id>{}(std::this_thread::get_id()) %
Expand All @@ -241,6 +252,9 @@ class object_cache {
/// \brief Get CPU core number.
/// This function does not call the system call every time as it is slow.
static std::size_t priv_get_core_no() {
#ifdef METALL_SINGLE_THREAD_ALLOC
return 0;
#endif
thread_local static int cached_core_no = 0;
thread_local static int cached_count = 0;
if (cached_core_no == 0) {
Expand All @@ -251,14 +265,18 @@ class object_cache {
}

static std::size_t get_num_cores() {
#ifdef METALL_SINGLE_THREAD_ALLOC
return 1;
#else
return std::thread::hardware_concurrency();
#endif
}

// -------------------- //
// Private fields
// -------------------- //
cache_table_type m_cache_table;
#if ENABLE_MUTEX_IN_METALL_OBJECT_CACHE
#ifdef METALL_ENABLE_MUTEX_IN_OBJECT_CACHE
std::vector<mutex_type> m_mutex;
#endif
};
Expand Down
3 changes: 3 additions & 0 deletions test/kernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ add_metall_test_executable(chunk_directory_test chunk_directory_test.cpp)

add_metall_test_executable(manager_test manager_test.cpp)

add_metall_test_executable(manager_test_single_thread manager_test.cpp)
target_compile_definitions(manager_test_single_thread PRIVATE METALL_SINGLE_THREAD_ALLOC)

add_metall_test_executable(snapshot_test snapshot_test.cpp)

add_metall_test_executable(copy_file_test copy_file_test.cpp)
Expand Down

0 comments on commit 47dea96

Please sign in to comment.