mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
modify test cases of mem;
sync_pool_alloc => async_pool_alloc, synchronized => async_wrapper; statical => static_wrapper; optimize ipc::mem::allocator; use std::hardware_destructive_interference_size for cache_line_size (TBD); simplified codes.
This commit is contained in:
parent
0beb0b4a13
commit
36d85e4b41
BIN
performance.xlsx
BIN
performance.xlsx
Binary file not shown.
@ -12,10 +12,6 @@
|
|||||||
namespace ipc {
|
namespace ipc {
|
||||||
namespace circ {
|
namespace circ {
|
||||||
|
|
||||||
enum {
|
|
||||||
cache_line_size = 64
|
|
||||||
};
|
|
||||||
|
|
||||||
using u1_t = ipc::uint_t<8>;
|
using u1_t = ipc::uint_t<8>;
|
||||||
using u2_t = ipc::uint_t<32>;
|
using u2_t = ipc::uint_t<32>;
|
||||||
|
|
||||||
|
|||||||
0
src/ipc.cpp
Executable file → Normal file
0
src/ipc.cpp
Executable file → Normal file
@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <atomic>
|
|
||||||
#include <thread>
|
|
||||||
#include <mutex>
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
@ -31,10 +28,6 @@ public:
|
|||||||
static void free(void* p, std::size_t /*size*/) {
|
static void free(void* p, std::size_t /*size*/) {
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::size_t size_of(void* /*p*/) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
@ -54,8 +47,8 @@ public:
|
|||||||
void free(void* /*p*/) {}
|
void free(void* /*p*/) {}
|
||||||
void free(void* /*p*/, std::size_t) {}
|
void free(void* /*p*/, std::size_t) {}
|
||||||
|
|
||||||
constexpr std::size_t size_of(void* /*p*/) const {
|
void swap(scope_alloc_base & rhs) {
|
||||||
return 0;
|
std::swap(this->list_, rhs.list_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,6 +57,7 @@ public:
|
|||||||
template <typename AllocP = static_alloc>
|
template <typename AllocP = static_alloc>
|
||||||
class scope_alloc : public detail::scope_alloc_base {
|
class scope_alloc : public detail::scope_alloc_base {
|
||||||
public:
|
public:
|
||||||
|
using base_t = detail::scope_alloc_base;
|
||||||
using alloc_policy = AllocP;
|
using alloc_policy = AllocP;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -80,7 +74,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
void swap(scope_alloc& rhs) {
|
void swap(scope_alloc& rhs) {
|
||||||
std::swap(this->alloc_, rhs.alloc_);
|
std::swap(this->alloc_, rhs.alloc_);
|
||||||
std::swap(this->list_ , rhs.list_);
|
base_t::swap(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
@ -106,6 +100,14 @@ public:
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
template <std::size_t BlockSize>
|
||||||
|
struct fixed_expand_policy {
|
||||||
|
static std::size_t next(std::size_t & e) {
|
||||||
|
static constexpr std::size_t basic_size = (ipc::detail::max)(BlockSize, static_cast<std::size_t>(2048));
|
||||||
|
return basic_size * (e *= 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class fixed_alloc_base {
|
class fixed_alloc_base {
|
||||||
protected:
|
protected:
|
||||||
std::size_t init_expand_;
|
std::size_t init_expand_;
|
||||||
@ -113,7 +115,7 @@ protected:
|
|||||||
|
|
||||||
void init(std::size_t init_expand) {
|
void init(std::size_t init_expand) {
|
||||||
init_expand_ = init_expand;
|
init_expand_ = init_expand;
|
||||||
cursor_ = nullptr;
|
cursor_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void** node_p(void* node) {
|
static void** node_p(void* node) {
|
||||||
@ -127,7 +129,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
void swap(fixed_alloc_base& rhs) {
|
void swap(fixed_alloc_base& rhs) {
|
||||||
std::swap(this->init_expand_, rhs.init_expand_);
|
std::swap(this->init_expand_, rhs.init_expand_);
|
||||||
std::swap(this->cursor_ , rhs.cursor_ );
|
std::swap(this->cursor_ , rhs.cursor_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free(void* p) {
|
void free(void* p) {
|
||||||
@ -143,7 +145,7 @@ public:
|
|||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <std::size_t BlockSize, typename AllocP = scope_alloc<>>
|
template <std::size_t BlockSize, template <std::size_t> class ExpandP = detail::fixed_expand_policy, typename AllocP = scope_alloc<>>
|
||||||
class fixed_alloc : public detail::fixed_alloc_base {
|
class fixed_alloc : public detail::fixed_alloc_base {
|
||||||
public:
|
public:
|
||||||
using base_t = detail::fixed_alloc_base;
|
using base_t = detail::fixed_alloc_base;
|
||||||
@ -160,9 +162,9 @@ private:
|
|||||||
if (this->cursor_ != nullptr) {
|
if (this->cursor_ != nullptr) {
|
||||||
return this->cursor_;
|
return this->cursor_;
|
||||||
}
|
}
|
||||||
auto p = this->node_p(this->cursor_ = alloc_.alloc(block_size));
|
auto size = ExpandP<block_size>::next(this->init_expand_);
|
||||||
auto size = alloc_.size_of(p);
|
auto p = this->node_p(this->cursor_ = alloc_.alloc(size));
|
||||||
if (size > 0) for (std::size_t i = 0; i < (size / block_size) - 1; ++i)
|
for (std::size_t i = 0; i < (size / block_size) - 1; ++i)
|
||||||
p = this->node_p((*p) = reinterpret_cast<byte_t*>(p) + block_size);
|
p = this->node_p((*p) = reinterpret_cast<byte_t*>(p) + block_size);
|
||||||
(*p) = nullptr;
|
(*p) = nullptr;
|
||||||
return this->cursor_;
|
return this->cursor_;
|
||||||
@ -187,10 +189,6 @@ public:
|
|||||||
this->init(this->init_expand_);
|
this->init(this->init_expand_);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr std::size_t size_of(void* /*p*/) const {
|
|
||||||
return block_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* alloc() {
|
void* alloc() {
|
||||||
void* p = try_expand();
|
void* p = try_expand();
|
||||||
this->cursor_ = this->next(p);
|
this->cursor_ = this->next(p);
|
||||||
@ -202,14 +200,5 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
/// page memory allocation
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
using page_alloc = fixed_alloc<4096>;
|
|
||||||
|
|
||||||
template <std::size_t BlockSize>
|
|
||||||
using page_fixed_alloc = fixed_alloc<BlockSize, page_alloc>;
|
|
||||||
|
|
||||||
} // namespace mem
|
} // namespace mem
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
|
|||||||
@ -13,14 +13,6 @@ enum : std::size_t {
|
|||||||
base_size = sizeof(void*)
|
base_size = sizeof(void*)
|
||||||
};
|
};
|
||||||
|
|
||||||
template <std::size_t Size, template <std::size_t> class FixedAlloc>
|
|
||||||
struct fixed {
|
|
||||||
static auto& pool() {
|
|
||||||
static FixedAlloc<Size> pool;
|
|
||||||
return pool;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#if __cplusplus >= 201703L
|
#if __cplusplus >= 201703L
|
||||||
constexpr std::size_t classify(std::size_t size) {
|
constexpr std::size_t classify(std::size_t size) {
|
||||||
constexpr std::size_t mapping[] = {
|
constexpr std::size_t mapping[] = {
|
||||||
@ -51,18 +43,18 @@ inline std::size_t classify(std::size_t size) {
|
|||||||
template <template <std::size_t> class Fixed, typename F>
|
template <template <std::size_t> class Fixed, typename F>
|
||||||
decltype(auto) choose(std::size_t size, F&& f) {
|
decltype(auto) choose(std::size_t size, F&& f) {
|
||||||
return ipc::detail::static_switch<32>(classify(size), [&f](auto index) {
|
return ipc::detail::static_switch<32>(classify(size), [&f](auto index) {
|
||||||
return f(Fixed<(decltype(index)::value + 1) * base_size>::pool());
|
return f(Fixed<(decltype(index)::value + 1) * base_size>::instance());
|
||||||
}, [&f] {
|
}, [&f] {
|
||||||
return f(static_alloc{});
|
return f(static_alloc{});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <std::size_t> class Fixed>
|
template <template <std::size_t> class Fixed>
|
||||||
class pool_alloc {
|
class fixed_alloc_policy {
|
||||||
public:
|
public:
|
||||||
static void clear() {
|
static void clear() {
|
||||||
ipc::detail::static_for<32>([](auto index) {
|
ipc::detail::static_for<32>([](auto index) {
|
||||||
Fixed<(decltype(index)::value + 1) * base_size>::pool().clear();
|
Fixed<(decltype(index)::value + 1) * base_size>::instance().clear();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
src/memory/resource.h
Executable file → Normal file
10
src/memory/resource.h
Executable file → Normal file
@ -19,15 +19,11 @@ namespace ipc {
|
|||||||
namespace mem {
|
namespace mem {
|
||||||
|
|
||||||
template <std::size_t Size>
|
template <std::size_t Size>
|
||||||
using sync_fixed_alloc = mem::synchronized<page_fixed_alloc<Size>>;
|
using static_async_fixed = mem::static_wrapper<mem::async_wrapper<mem::fixed_alloc<Size>>>;
|
||||||
|
using async_pool_alloc = mem::detail::fixed_alloc_policy<static_async_fixed>;
|
||||||
template <std::size_t Size>
|
|
||||||
using sync_fixed = mem::detail::fixed<Size, sync_fixed_alloc>;
|
|
||||||
|
|
||||||
using sync_pool_alloc = mem::detail::pool_alloc<sync_fixed>;
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using allocator = allocator_wrapper<T, sync_pool_alloc>;
|
using allocator = allocator_wrapper<T, async_pool_alloc>;
|
||||||
|
|
||||||
} // namespace mem
|
} // namespace mem
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <map>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -128,76 +128,62 @@ constexpr bool operator!=(const allocator_wrapper<T, AllocP>&, const allocator_w
|
|||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template <typename AllocP>
|
template <typename AllocP>
|
||||||
class synchronized {
|
class async_wrapper {
|
||||||
public:
|
public:
|
||||||
using alloc_policy = AllocP;
|
using alloc_policy = AllocP;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
spin_lock lc_;
|
class alloc_proxy : public alloc_policy {
|
||||||
std::multimap<std::size_t, alloc_policy*> allocs_;
|
async_wrapper * w_ = nullptr;
|
||||||
|
|
||||||
struct alloc_t {
|
public:
|
||||||
synchronized* t_;
|
alloc_proxy(alloc_proxy&& rhs)
|
||||||
std::size_t s_ = 0;
|
: alloc_policy(std::move(rhs))
|
||||||
alloc_policy* a_ = nullptr;
|
{}
|
||||||
|
|
||||||
alloc_t(synchronized* t)
|
alloc_proxy(async_wrapper* w)
|
||||||
: t_ { t } {
|
: alloc_policy(), w_(w) {
|
||||||
{
|
if (w_ == nullptr) return;
|
||||||
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(t_->lc_);
|
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(w_->master_lock_);
|
||||||
auto it = t_->allocs_.begin();
|
if (!w_->master_allocs_.empty()) {
|
||||||
if (it != t_->allocs_.end()) {
|
alloc_policy::swap(w_->master_allocs_.back());
|
||||||
std::tie(s_, a_) = *it;
|
w_->master_allocs_.pop_back();
|
||||||
t_->allocs_.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (a_ == nullptr) {
|
|
||||||
a_ = new alloc_policy;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~alloc_t() {
|
~alloc_proxy() {
|
||||||
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(t_->lc_);
|
if (w_ == nullptr) return;
|
||||||
t_->allocs_.emplace(s_, a_);
|
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(w_->master_lock_);
|
||||||
}
|
w_->master_allocs_.emplace_back(std::move(*this));
|
||||||
|
|
||||||
void* alloc(std::size_t size) {
|
|
||||||
void* p = a_->alloc(size);
|
|
||||||
if ((p != nullptr) && (s_ > 0)) {
|
|
||||||
--s_;
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free(void* p) {
|
|
||||||
a_->free(p);
|
|
||||||
++s_;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto& alc_info() {
|
friend class alloc_proxy;
|
||||||
static tls::pointer<alloc_t> alc;
|
|
||||||
return *alc.create(this);
|
spin_lock master_lock_;
|
||||||
|
std::vector<alloc_proxy> master_allocs_;
|
||||||
|
|
||||||
|
auto& get_alloc() {
|
||||||
|
static tls::pointer<alloc_proxy> tls_alc;
|
||||||
|
return *tls_alc.create(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~synchronized() {
|
~async_wrapper() {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(lc_);
|
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(master_lock_);
|
||||||
for (auto& pair : allocs_) {
|
master_allocs_.clear();
|
||||||
delete pair.second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* alloc(std::size_t size) {
|
void* alloc(std::size_t size) {
|
||||||
return alc_info().alloc(size);
|
return get_alloc().alloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free(void* p) {
|
void free(void* p) {
|
||||||
alc_info().free(p);
|
get_alloc().free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free(void* p, std::size_t /*size*/) {
|
void free(void* p, std::size_t /*size*/) {
|
||||||
@ -210,7 +196,7 @@ public:
|
|||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template <typename AllocP>
|
template <typename AllocP>
|
||||||
class statical {
|
class static_wrapper {
|
||||||
public:
|
public:
|
||||||
using alloc_policy = AllocP;
|
using alloc_policy = AllocP;
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
@ -137,5 +138,14 @@ inline void static_for(F&& f) {
|
|||||||
static_for(std::make_index_sequence<N>{}, std::forward<F>(f));
|
static_for(std::make_index_sequence<N>{}, std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Minimum offset between two objects to avoid false sharing.
|
||||||
|
enum {
|
||||||
|
// #if __cplusplus >= 201703L
|
||||||
|
// cache_line_size = std::hardware_destructive_interference_size
|
||||||
|
// #else /*__cplusplus < 201703L*/
|
||||||
|
cache_line_size = 64
|
||||||
|
// #endif/*__cplusplus < 201703L*/
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
|
|||||||
@ -6,15 +6,15 @@ namespace ipc {
|
|||||||
namespace mem {
|
namespace mem {
|
||||||
|
|
||||||
void pool_alloc::clear() {
|
void pool_alloc::clear() {
|
||||||
sync_pool_alloc::clear();
|
async_pool_alloc::clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* pool_alloc::alloc(std::size_t size) {
|
void* pool_alloc::alloc(std::size_t size) {
|
||||||
return sync_pool_alloc::alloc(size);
|
return async_pool_alloc::alloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pool_alloc::free(void* p, std::size_t size) {
|
void pool_alloc::free(void* p, std::size_t size) {
|
||||||
sync_pool_alloc::free(p, size);
|
async_pool_alloc::free(p, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mem
|
} // namespace mem
|
||||||
|
|||||||
@ -26,8 +26,8 @@ struct prod_cons_impl<wr<relat::single, relat::single, trans::unicast>> {
|
|||||||
std::aligned_storage_t<DataSize, AlignSize> data_ {};
|
std::aligned_storage_t<DataSize, AlignSize> data_ {};
|
||||||
};
|
};
|
||||||
|
|
||||||
alignas(circ::cache_line_size) std::atomic<circ::u2_t> rd_; // read index
|
alignas(detail::cache_line_size) std::atomic<circ::u2_t> rd_; // read index
|
||||||
alignas(circ::cache_line_size) std::atomic<circ::u2_t> wt_; // write index
|
alignas(detail::cache_line_size) std::atomic<circ::u2_t> wt_; // write index
|
||||||
|
|
||||||
constexpr circ::u2_t cursor() const noexcept {
|
constexpr circ::u2_t cursor() const noexcept {
|
||||||
return 0;
|
return 0;
|
||||||
@ -96,7 +96,7 @@ struct prod_cons_impl<wr<relat::multi , relat::multi, trans::unicast>>
|
|||||||
std::atomic<flag_t> f_ct_ { 0 }; // commit flag
|
std::atomic<flag_t> f_ct_ { 0 }; // commit flag
|
||||||
};
|
};
|
||||||
|
|
||||||
alignas(circ::cache_line_size) std::atomic<circ::u2_t> ct_; // commit index
|
alignas(detail::cache_line_size) std::atomic<circ::u2_t> ct_; // commit index
|
||||||
|
|
||||||
template <typename W, typename F, typename E>
|
template <typename W, typename F, typename E>
|
||||||
bool push(W* /*wrapper*/, F&& f, E* elems) {
|
bool push(W* /*wrapper*/, F&& f, E* elems) {
|
||||||
@ -182,7 +182,7 @@ struct prod_cons_impl<wr<relat::single, relat::multi, trans::broadcast>> {
|
|||||||
std::atomic<rc_t> rc_ { 0 }; // read-counter
|
std::atomic<rc_t> rc_ { 0 }; // read-counter
|
||||||
};
|
};
|
||||||
|
|
||||||
alignas(circ::cache_line_size) std::atomic<circ::u2_t> wt_; // write index
|
alignas(detail::cache_line_size) std::atomic<circ::u2_t> wt_; // write index
|
||||||
|
|
||||||
circ::u2_t cursor() const noexcept {
|
circ::u2_t cursor() const noexcept {
|
||||||
return wt_.load(std::memory_order_acquire);
|
return wt_.load(std::memory_order_acquire);
|
||||||
@ -276,7 +276,7 @@ struct prod_cons_impl<wr<relat::multi , relat::multi, trans::broadcast>> {
|
|||||||
std::atomic<flag_t> f_ct_ { 0 }; // commit flag
|
std::atomic<flag_t> f_ct_ { 0 }; // commit flag
|
||||||
};
|
};
|
||||||
|
|
||||||
alignas(circ::cache_line_size) std::atomic<circ::u2_t> ct_; // commit index
|
alignas(detail::cache_line_size) std::atomic<circ::u2_t> ct_; // commit index
|
||||||
|
|
||||||
circ::u2_t cursor() const noexcept {
|
circ::u2_t cursor() const noexcept {
|
||||||
return ct_.load(std::memory_order_acquire);
|
return ct_.load(std::memory_order_acquire);
|
||||||
|
|||||||
@ -238,7 +238,7 @@ private slots:
|
|||||||
void test_prod_cons_1v3();
|
void test_prod_cons_1v3();
|
||||||
void test_prod_cons_performance();
|
void test_prod_cons_performance();
|
||||||
void test_queue();
|
void test_queue();
|
||||||
} /*unit__*/;
|
} unit__;
|
||||||
|
|
||||||
#include "test_circ.moc"
|
#include "test_circ.moc"
|
||||||
|
|
||||||
|
|||||||
@ -23,14 +23,15 @@ private slots:
|
|||||||
void initTestCase();
|
void initTestCase();
|
||||||
|
|
||||||
void test_alloc_free();
|
void test_alloc_free();
|
||||||
void test_linear();
|
void test_static();
|
||||||
} /*unit__*/;
|
void test_pool();
|
||||||
|
} unit__;
|
||||||
|
|
||||||
#include "test_mem.moc"
|
#include "test_mem.moc"
|
||||||
|
|
||||||
constexpr int DataMin = sizeof(void*);
|
constexpr int DataMin = sizeof(void*);
|
||||||
constexpr int DataMax = sizeof(void*) * 16;
|
constexpr int DataMax = sizeof(void*) * 16;
|
||||||
constexpr int LoopCount = 1000000;
|
constexpr int LoopCount = 10000000;
|
||||||
|
|
||||||
std::vector<std::size_t> sizes__;
|
std::vector<std::size_t> sizes__;
|
||||||
|
|
||||||
@ -106,7 +107,7 @@ void benchmark_alloc() {
|
|||||||
|
|
||||||
void Unit::test_alloc_free() {
|
void Unit::test_alloc_free() {
|
||||||
benchmark_alloc<ipc::mem::static_alloc>();
|
benchmark_alloc<ipc::mem::static_alloc>();
|
||||||
benchmark_alloc<ipc::mem::sync_pool_alloc>();
|
benchmark_alloc<ipc::mem::async_pool_alloc>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename AllocT, typename ModeT, int ThreadsN>
|
template <typename AllocT, typename ModeT, int ThreadsN>
|
||||||
@ -145,7 +146,7 @@ void benchmark_alloc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((fini.fetch_add(1, std::memory_order_relaxed) + 1) == ThreadsN) {
|
if ((fini.fetch_add(1, std::memory_order_relaxed) + 1) == ThreadsN) {
|
||||||
sw.print_elapsed<1>(DataMin, DataMax, LoopCount);
|
sw.print_elapsed<1>(DataMin, DataMax, LoopCount * ThreadsN);
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
++pid;
|
++pid;
|
||||||
@ -170,15 +171,16 @@ struct test_performance<AllocT, ModeT, 1> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Unit::test_linear() {
|
void Unit::test_static() {
|
||||||
test_performance<ipc::mem::static_alloc, alloc_random, 8>::start();
|
|
||||||
test_performance<ipc::mem::pool_alloc , alloc_random, 8>::start();
|
|
||||||
|
|
||||||
test_performance<ipc::mem::static_alloc, alloc_LIFO , 8>::start();
|
|
||||||
test_performance<ipc::mem::pool_alloc , alloc_LIFO , 8>::start();
|
|
||||||
|
|
||||||
test_performance<ipc::mem::static_alloc, alloc_FIFO , 8>::start();
|
test_performance<ipc::mem::static_alloc, alloc_FIFO , 8>::start();
|
||||||
test_performance<ipc::mem::pool_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();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unit::test_pool() {
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // internal-linkage
|
} // internal-linkage
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user