mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
optimize memory allocator for big size memory
This commit is contained in:
parent
981124520c
commit
c8cedf11cf
6
build/test/CMakeLists.txt
Normal file → Executable file
6
build/test/CMakeLists.txt
Normal file → Executable file
@ -9,12 +9,12 @@ if(NOT MSVC)
|
||||
add_compile_options(-Wno-attributes -Wno-missing-field-initializers -Wno-unused-variable -Wno-unused-function)
|
||||
endif()
|
||||
|
||||
include_directories(../../include ../../src ../../test ../../test/capo)
|
||||
include_directories(../../include ../../src ../../test)
|
||||
file(GLOB SRC_FILES ../../test/*.cpp)
|
||||
file(GLOB HEAD_FILES ../../test/*.h)
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../output)
|
||||
|
||||
link_directories(${EXECUTABLE_OUTPUT_PATH})
|
||||
link_directories(${EXECUTABLE_OUTPUT_PATH} ${CMAKE_SOURCE_DIR}/../test/gperftools)
|
||||
add_subdirectory(../ipc ipc.out)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SRC_FILES} ${HEAD_FILES})
|
||||
@ -22,3 +22,5 @@ target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Test ipc)
|
||||
if(NOT MSVC)
|
||||
target_link_libraries(${PROJECT_NAME} pthread rt)
|
||||
endif()
|
||||
|
||||
#target_link_libraries(${PROJECT_NAME} tcmalloc_minimal)
|
||||
|
||||
@ -18,7 +18,6 @@ DESTDIR = ../../output
|
||||
|
||||
INCLUDEPATH += \
|
||||
../../test \
|
||||
../../test/capo \
|
||||
../../include \
|
||||
../../src
|
||||
|
||||
@ -36,4 +35,6 @@ SOURCES += \
|
||||
LIBS += \
|
||||
-L$${DESTDIR} -lipc
|
||||
|
||||
unix:LIBS += -lrt -lpthread
|
||||
unix:LIBS += \
|
||||
# -L../../test/gperftools -ltcmalloc_minimal \
|
||||
-lrt -lpthread
|
||||
|
||||
BIN
performance.xlsx
BIN
performance.xlsx
Binary file not shown.
@ -26,7 +26,14 @@ using static_async_fixed =
|
||||
static_wrapper<async_wrapper<fixed_alloc<
|
||||
Size, chunk_variable_alloc >>>;
|
||||
|
||||
using async_pool_alloc = /*static_alloc*/variable_wrapper<static_async_fixed>;
|
||||
using big_size_alloc = variable_wrapper<static_async_fixed,
|
||||
default_mapping_policy<
|
||||
default_mapping_policy<>::block_size(default_mapping_policy<>::classes_size),
|
||||
default_mapping_policy<>::iter_size * 2 >>;
|
||||
|
||||
using async_pool_alloc = variable_wrapper<static_async_fixed,
|
||||
default_mapping_policy<>,
|
||||
big_size_alloc>;
|
||||
|
||||
template <typename T>
|
||||
using allocator = allocator_wrapper<T, async_pool_alloc>;
|
||||
|
||||
@ -335,30 +335,31 @@ public:
|
||||
/// Variable memory allocation wrapper
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
template <std::size_t BaseSize = sizeof(void*)>
|
||||
template <std::size_t BaseSize = 0, std::size_t IterSize = sizeof(void*)>
|
||||
struct default_mapping_policy {
|
||||
|
||||
enum : std::size_t {
|
||||
base_size = BaseSize,
|
||||
iter_size = IterSize,
|
||||
classes_size = 32
|
||||
};
|
||||
|
||||
static const std::size_t table[classes_size];
|
||||
|
||||
IPC_CONSTEXPR_ static std::size_t classify(std::size_t size) noexcept {
|
||||
auto index = (size - 1) / base_size;
|
||||
auto index = (size <= base_size) ? 0 : ((size - base_size - 1) / iter_size);
|
||||
return (index < classes_size) ?
|
||||
// always uses default_mapping_policy<sizeof(void*)>::table
|
||||
// always uses default_mapping_policy<>::table
|
||||
default_mapping_policy<>::table[index] : classes_size;
|
||||
}
|
||||
|
||||
constexpr static std::size_t block_size(std::size_t value) noexcept {
|
||||
return (value + 1) * base_size;
|
||||
return base_size + (value + 1) * iter_size;
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t B>
|
||||
const std::size_t default_mapping_policy<B>::table[default_mapping_policy<B>::classes_size] = {
|
||||
template <std::size_t B, std::size_t I>
|
||||
const std::size_t default_mapping_policy<B, I>::table[default_mapping_policy<B, I>::classes_size] = {
|
||||
/* 1 - 8 ~ 32 */
|
||||
0 , 1 , 2 , 3 ,
|
||||
/* 2 - 48 ~ 256 */
|
||||
|
||||
BIN
test/gperftools/libtcmalloc_minimal.so
Executable file
BIN
test/gperftools/libtcmalloc_minimal.so
Executable file
Binary file not shown.
1
test/gperftools/libtcmalloc_minimal.so.4
Symbolic link
1
test/gperftools/libtcmalloc_minimal.so.4
Symbolic link
@ -0,0 +1 @@
|
||||
libtcmalloc_minimal.so
|
||||
1
test/gperftools/libtcmalloc_minimal.so.4.5.3
Symbolic link
1
test/gperftools/libtcmalloc_minimal.so.4.5.3
Symbolic link
@ -0,0 +1 @@
|
||||
libtcmalloc_minimal.so
|
||||
163
test/gperftools/tcmalloc.h
Executable file
163
test/gperftools/tcmalloc.h
Executable file
@ -0,0 +1,163 @@
|
||||
// -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*-
|
||||
/* Copyright (c) 2003, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ---
|
||||
* Author: Sanjay Ghemawat <opensource@google.com>
|
||||
* .h file by Craig Silverstein <opensource@google.com>
|
||||
*/
|
||||
|
||||
#ifndef TCMALLOC_TCMALLOC_H_
|
||||
#define TCMALLOC_TCMALLOC_H_
|
||||
|
||||
#include <stddef.h> /* for size_t */
|
||||
#ifdef __cplusplus
|
||||
#include <new> /* for std::nothrow_t, std::align_val_t */
|
||||
#endif
|
||||
|
||||
/* Define the version number so folks can check against it */
|
||||
#define TC_VERSION_MAJOR 2
|
||||
#define TC_VERSION_MINOR 7
|
||||
#define TC_VERSION_PATCH ""
|
||||
#define TC_VERSION_STRING "gperftools 2.7"
|
||||
|
||||
/* For struct mallinfo, if it's defined. */
|
||||
#if 1
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifndef PERFTOOLS_NOTHROW
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#define PERFTOOLS_NOTHROW noexcept
|
||||
#elif defined(__cplusplus)
|
||||
#define PERFTOOLS_NOTHROW throw()
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# define PERFTOOLS_NOTHROW __attribute__((__nothrow__))
|
||||
# else
|
||||
# define PERFTOOLS_NOTHROW
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef PERFTOOLS_DLL_DECL
|
||||
# ifdef _WIN32
|
||||
# define PERFTOOLS_DLL_DECL __declspec(dllimport)
|
||||
# else
|
||||
# define PERFTOOLS_DLL_DECL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Returns a human-readable version string. If major, minor,
|
||||
* and/or patch are not NULL, they are set to the major version,
|
||||
* minor version, and patch-code (a string, usually "").
|
||||
*/
|
||||
PERFTOOLS_DLL_DECL const char* tc_version(int* major, int* minor,
|
||||
const char** patch) PERFTOOLS_NOTHROW;
|
||||
|
||||
PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_free(void* ptr) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) PERFTOOLS_NOTHROW;
|
||||
|
||||
PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,
|
||||
size_t __size) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,
|
||||
size_t align, size_t size) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) PERFTOOLS_NOTHROW;
|
||||
|
||||
PERFTOOLS_DLL_DECL void tc_malloc_stats(void) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHROW;
|
||||
#if 1
|
||||
PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is an alias for MallocExtension::instance()->GetAllocatedSize().
|
||||
* It is equivalent to
|
||||
* OS X: malloc_size()
|
||||
* glibc: malloc_usable_size()
|
||||
* Windows: _msize()
|
||||
*/
|
||||
PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) PERFTOOLS_NOTHROW;
|
||||
|
||||
#ifdef __cplusplus
|
||||
PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void* tc_new(size_t size);
|
||||
PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
|
||||
const std::nothrow_t&) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_delete(void* p) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
|
||||
const std::nothrow_t&) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
|
||||
PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
|
||||
const std::nothrow_t&) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_deletearray(void* p) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
|
||||
const std::nothrow_t&) PERFTOOLS_NOTHROW;
|
||||
|
||||
#if 1 && __cplusplus >= 201703L
|
||||
PERFTOOLS_DLL_DECL void* tc_new_aligned(size_t size, std::align_val_t al);
|
||||
PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::align_val_t al,
|
||||
const std::nothrow_t&) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t al,
|
||||
const std::nothrow_t&) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t al);
|
||||
PERFTOOLS_DLL_DECL void* tc_newarray_aligned_nothrow(size_t size, std::align_val_t al,
|
||||
const std::nothrow_t&) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_deletearray_aligned(void* p, std::align_val_t al) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_deletearray_sized_aligned(void* p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW;
|
||||
PERFTOOLS_DLL_DECL void tc_deletearray_aligned_nothrow(void* p, std::align_val_t al,
|
||||
const std::nothrow_t&) PERFTOOLS_NOTHROW;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We're only un-defining for public */
|
||||
#if !defined(GPERFTOOLS_CONFIG_H_)
|
||||
|
||||
#undef PERFTOOLS_NOTHROW
|
||||
|
||||
#endif /* GPERFTOOLS_CONFIG_H_ */
|
||||
|
||||
#endif /* #ifndef TCMALLOC_TCMALLOC_H_ */
|
||||
@ -13,8 +13,8 @@
|
||||
# include <cxxabi.h> // abi::__cxa_demangle
|
||||
#endif/*__GNUC__*/
|
||||
|
||||
#include "stopwatch.hpp"
|
||||
#include "spin_lock.hpp"
|
||||
#include "capo/stopwatch.hpp"
|
||||
#include "capo/spin_lock.hpp"
|
||||
|
||||
class TestSuite : public QObject
|
||||
{
|
||||
|
||||
@ -13,9 +13,9 @@
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
||||
#include "stopwatch.hpp"
|
||||
#include "spin_lock.hpp"
|
||||
#include "random.hpp"
|
||||
#include "capo/stopwatch.hpp"
|
||||
#include "capo/spin_lock.hpp"
|
||||
#include "capo/random.hpp"
|
||||
|
||||
#include "ipc.h"
|
||||
#include "rw_lock.h"
|
||||
|
||||
@ -3,11 +3,13 @@
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
|
||||
#include "random.hpp"
|
||||
#include "capo/random.hpp"
|
||||
|
||||
#include "memory/resource.h"
|
||||
#include "pool_alloc.h"
|
||||
|
||||
//#include "gperftools/tcmalloc.h"
|
||||
|
||||
#include "test.h"
|
||||
|
||||
namespace {
|
||||
@ -23,15 +25,13 @@ private slots:
|
||||
void initTestCase();
|
||||
|
||||
void test_alloc_free();
|
||||
void test_static();
|
||||
void test_pool();
|
||||
} unit__;
|
||||
|
||||
#include "test_mem.moc"
|
||||
|
||||
constexpr int DataMin = sizeof(void*);
|
||||
constexpr int DataMax = sizeof(void*) * 16;
|
||||
constexpr int LoopCount = 1000000;
|
||||
constexpr int DataMin = 4;
|
||||
constexpr int DataMax = 256;
|
||||
constexpr int LoopCount = 100000;
|
||||
|
||||
std::vector<std::size_t> sizes__;
|
||||
|
||||
@ -96,18 +96,13 @@ void benchmark_alloc() {
|
||||
test_stopwatch sw;
|
||||
sw.start();
|
||||
|
||||
for (std::size_t x = 0; x < 10; ++x)
|
||||
for (std::size_t k = 0; k < 100; ++k)
|
||||
for (std::size_t n = 0; n < LoopCount; ++n) {
|
||||
std::size_t s = sizes__[n];
|
||||
AllocT::free(AllocT::alloc(s), s);
|
||||
}
|
||||
|
||||
sw.print_elapsed<1>(DataMin, DataMax, LoopCount * 10);
|
||||
}
|
||||
|
||||
void Unit::test_alloc_free() {
|
||||
benchmark_alloc<ipc::mem::static_alloc>();
|
||||
benchmark_alloc<ipc::mem::async_pool_alloc>();
|
||||
sw.print_elapsed<1>(DataMin, DataMax, LoopCount * 100);
|
||||
}
|
||||
|
||||
template <typename AllocT, typename ModeT, int ThreadsN>
|
||||
@ -131,6 +126,7 @@ void benchmark_alloc() {
|
||||
for (auto& w : works) {
|
||||
w = std::thread {[&, pid] {
|
||||
sw.start();
|
||||
for (std::size_t k = 0; k < 10; ++k)
|
||||
for (std::size_t x = 0; x < 2; ++x) {
|
||||
for(std::size_t n = 0; n < LoopCount; ++n) {
|
||||
int m = mode.ix_[x][n];
|
||||
@ -146,7 +142,7 @@ void benchmark_alloc() {
|
||||
}
|
||||
}
|
||||
if ((fini.fetch_add(1, std::memory_order_relaxed) + 1) == ThreadsN) {
|
||||
sw.print_elapsed<1>(DataMin, DataMax, LoopCount * ThreadsN);
|
||||
sw.print_elapsed<1>(DataMin, DataMax, LoopCount * 10 * ThreadsN);
|
||||
}
|
||||
}};
|
||||
++pid;
|
||||
@ -171,19 +167,29 @@ struct test_performance<AllocT, ModeT, 1> {
|
||||
}
|
||||
};
|
||||
|
||||
void Unit::test_static() {
|
||||
test_performance<ipc::mem::static_alloc, alloc_FIFO , 8>::start();
|
||||
test_performance<ipc::mem::static_alloc, alloc_LIFO , 8>::start();
|
||||
test_performance<ipc::mem::static_alloc, alloc_random, 8>::start();
|
||||
}
|
||||
//class tc_alloc {
|
||||
//public:
|
||||
// static void clear() {}
|
||||
|
||||
void Unit::test_pool() {
|
||||
// test_performance<ipc::mem::pool_alloc, alloc_FIFO , 8>::start();
|
||||
// for (;;) {
|
||||
test_performance<ipc::mem::pool_alloc, alloc_FIFO , 8>::start();
|
||||
test_performance<ipc::mem::pool_alloc, alloc_LIFO , 8>::start();
|
||||
test_performance<ipc::mem::pool_alloc, alloc_random, 8>::start();
|
||||
// static void* alloc(std::size_t size) {
|
||||
// return size ? tc_malloc(size) : nullptr;
|
||||
// }
|
||||
|
||||
// static void free(void* p, std::size_t size) {
|
||||
// tc_free_sized(p, size);
|
||||
// }
|
||||
//};
|
||||
|
||||
#define TEST_ALLOC_TYPE /*ipc::mem::static_alloc*/ ipc::mem::async_pool_alloc /*tc_alloc*/
|
||||
|
||||
void Unit::test_alloc_free() {
|
||||
// benchmark_alloc <TEST_ALLOC_TYPE>();
|
||||
// test_performance<TEST_ALLOC_TYPE, alloc_FIFO , 24>::start();
|
||||
|
||||
benchmark_alloc <TEST_ALLOC_TYPE>();
|
||||
test_performance<TEST_ALLOC_TYPE, alloc_FIFO , 16>::start();
|
||||
test_performance<TEST_ALLOC_TYPE, alloc_LIFO , 16>::start();
|
||||
test_performance<TEST_ALLOC_TYPE, alloc_random, 16>::start();
|
||||
}
|
||||
|
||||
} // internal-linkage
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user