diff --git a/README.md b/README.md index 1f4f902..3b9e674 100644 --- a/README.md +++ b/README.md @@ -13,49 +13,16 @@ A high-performance inter-process communication using shared memory on Linux/Wind ## Performance - | Environment | Value | - | ------ | ------ | - | CPU | AMD Ryzen™ 5 1400 Quad-Core | - | RAM | 32 GB | - | OS | Windows 10 Pro for Education x64 | - | Compiler | MSVC 2017 15.9.4 x64 | + Environment | Value + ------ | ------ + Device | Lenovo ThinkPad T450 + CPU | Intel® Core™ i5-4300U @ 2.5 GHz + RAM | 16 GB + OS | Windows 7 Ultimate x64 + Compiler | MSVC 2017 15.9.4 -UT & benchmark test function, see: [test](test) - -### ipc::circ::queue - - | PROD-CONS: 1-N | DATAS: 12bits * 1000000 | - | ------ | ------ | - | `1-1` | `47.4050 ms, 0.047405 us/d` | - | `1-2` | `113.793 ms, 0.113793 us/d` | - | `1-4` | `319.196 ms, 0.319196 us/d` | - | `1-8` | `225.258 ms, 0.225258 us/d` | - -### ipc::route - - | PROD-CONS: 1-N | DATAS: Random 2-256bits * 100000 | - | ------ | ------ | - | `RTT` | `103.280 ms, 1.03280 us/d` | - | `1-1` | `78.6670 ms, 0.78667 us/d` | - | `1-2` | `165.601 ms, 1.65601 us/d` | - | `1-4` | `223.183 ms, 2.23183 us/d` | - | `1-8` | `246.161 ms, 2.46161 us/d` | - -### ipc::channel - - | PROD-CONS: N-M | DATAS: Random 2-256bits * 100000 | - | ------ | ------ | - | `RTT` | `184.711 ms, 1.84711 us/d` | - | `1-1` | `122.186 ms, 1.22186 us/d` | - | `1-2` | `226.518 ms, 2.26518 us/d` | - | `1-4` | `369.239 ms, 3.69239 us/d` | - | `1-8` | `620.199 ms, 6.20199 us/d` | - | `2-1` | `287.960 ms, 1.43980 us/d` | - | `4-1` | `542.050 ms, 1.35512 us/d` | - | `8-1` | `1406.61 ms, 1.75826 us/d` | - | `2-2` | `475.095 ms, 2.37547 us/d` | - | `4-4` | `1455.05 ms, 3.63763 us/d` | - | `8-8` | `5485.06 ms, 6.85633 us/d` | +UT & benchmark test function: [test](test) +Performance data: [performence.xlsx](performence.xlsx) ## Reference diff --git a/performence.xlsx b/performence.xlsx new file mode 100644 index 0000000..ce671a6 Binary files /dev/null and b/performence.xlsx differ diff --git a/src/memory/alloc.hpp b/src/memory/alloc.hpp index b869a68..bc071a3 100644 --- a/src/memory/alloc.hpp +++ b/src/memory/alloc.hpp @@ -153,8 +153,6 @@ public: fixed_pool(fixed_pool&& rhs) { this->swap(rhs); } fixed_pool& operator=(fixed_pool&& rhs) { this->swap(rhs); return (*this); } - ~fixed_pool() { clear(); } - public: void swap(fixed_pool& rhs) { std::swap(this->alloc_ , rhs.alloc_); diff --git a/src/memory/resource.hpp b/src/memory/resource.hpp index 7469da0..53de231 100644 --- a/src/memory/resource.hpp +++ b/src/memory/resource.hpp @@ -26,34 +26,50 @@ constexpr decltype(auto) static_switch(std::size_t i, std::index_sequence{}, f, def); } +template +constexpr void static_for(std::index_sequence, F&& f) { + [[maybe_unused]] auto expand = { (f(std::integral_constant{}), 0)... }; +} + template auto& fixed() { static synchronized> pool; return pool; } +enum : std::size_t { + base_size = sizeof(void*) +}; + +using fixed_sequence_t = std::index_sequence< + base_size , base_size * 2 , + base_size * 3 , base_size * 4 , + base_size * 5 , base_size * 6 , + base_size * 7 , base_size * 8 , + base_size * 9 , base_size * 10, + base_size * 11, base_size * 12, + base_size * 13, base_size * 14, + base_size * 15, base_size * 16 +>; + template decltype(auto) choose(std::size_t size, F&& f) { - enum : std::size_t { base_size = sizeof(void*) }; size = ((size - 1) & (~(base_size - 1))) + base_size; - return detail::static_switch(size, std::index_sequence< - base_size , base_size * 2 , - base_size * 3 , base_size * 4 , - base_size * 5 , base_size * 6 , - base_size * 7 , base_size * 8 , - base_size * 9 , base_size * 10, - base_size * 11, base_size * 12, - base_size * 13, base_size * 14, - base_size * 15, base_size * 16 - >{}, [&f](auto index) { + return detail::static_switch(size, fixed_sequence_t { + }, [&f](auto index) { return f(fixed()); - }, [&f] { return f(static_alloc{}); }); + }, [&f] { + return f(static_alloc{}); + }); } class pool_alloc { public: - static constexpr void clear() {} - static constexpr void swap(pool_alloc&) {} + static void clear() { + static_for(fixed_sequence_t {}, [](auto index) { + fixed().clear(); + }); + } static void* alloc(std::size_t size) { return choose(size, [size](auto&& fp) { return fp.alloc(size); }); diff --git a/src/memory/wrapper.hpp b/src/memory/wrapper.hpp index 55eab36..8ee6492 100644 --- a/src/memory/wrapper.hpp +++ b/src/memory/wrapper.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -80,6 +81,18 @@ public: } } + void clear() { + auto guard = std::unique_lock { lc_ }; + std::vector vec(allocs_.size()); + std::size_t i = 0; + for (auto& pair : allocs_) { + vec[i++] = pair.second; + } + allocs_.clear(); + guard.unlock(); + for (auto alc : vec) delete alc; + } + void* alloc(std::size_t size) { return alc_info().alloc(size); } @@ -88,7 +101,7 @@ public: alc_info().free(p); } - static void free(void* p, std::size_t /*size*/) { + void free(void* p, std::size_t /*size*/) { free(p); } }; diff --git a/test/main.cpp b/test/main.cpp index a2bc740..ce046ed 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -32,6 +32,8 @@ int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); Q_UNUSED(app) +// QThread::sleep(5); + int failed_count = 0; for (const auto& suite : (*suites__)) { if (QTest::qExec(suite, argc, argv) != 0) diff --git a/test/test_circ.cpp b/test/test_circ.cpp index ae7065b..6611848 100644 --- a/test/test_circ.cpp +++ b/test/test_circ.cpp @@ -8,6 +8,7 @@ #include "circ_elem_array.h" #include "circ_queue.h" +#include "memory/resource.hpp" #include "test.h" namespace { @@ -223,40 +224,11 @@ void Unit::test_prod_cons_1v3() { test_prod_cons<1, 3>(); } -template -struct test_performance { - static void start() { - test_performance

::start(); - test_prod_cons(); - } -}; - -template -struct test_performance<1, C> { - static void start() { - test_performance<1, C - 1>::start(); - test_prod_cons<1, C, false>(); - } -}; - -template -struct test_performance { - static void start() { - test_performance

::start(); - test_prod_cons(); - } -}; - -template <> -struct test_performance<1, 1> { - static void start() { - test_prod_cons<1, 1, false>(); - } -}; - void Unit::test_prod_cons_performance() { - test_performance<1, 10>::start(); - test_prod_cons <1, 10>(); // test & verify + ipc::mem::detail::static_for(std::make_index_sequence<10>{}, [](auto index) { + test_prod_cons<1, decltype(index)::value + 1, false>(); + }); + test_prod_cons<1, 10>(); // test & verify } void Unit::test_queue() { @@ -269,10 +241,9 @@ void Unit::test_queue() { queue.attach(cq); QVERIFY(queue.detach() != nullptr); - benchmark_prod_cons<1, 1, LoopCount>((ipc::circ::queue*)nullptr); - benchmark_prod_cons<1, 2, LoopCount>((ipc::circ::queue*)nullptr); - benchmark_prod_cons<1, 4, LoopCount>((ipc::circ::queue*)nullptr); - benchmark_prod_cons<1, 8, LoopCount>((ipc::circ::queue*)nullptr); + ipc::mem::detail::static_for(std::make_index_sequence<10>{}, [](auto index) { + benchmark_prod_cons<1, decltype(index)::value + 1, LoopCount>((ipc::circ::queue*)nullptr); + }); } } // internal-linkage diff --git a/test/test_ipc.cpp b/test/test_ipc.cpp index 04a86ea..bcb7157 100644 --- a/test/test_ipc.cpp +++ b/test/test_ipc.cpp @@ -19,6 +19,7 @@ #include "ipc.h" #include "rw_lock.h" +#include "memory/resource.hpp" #include "test.h" @@ -419,43 +420,11 @@ void Unit::test_route_rtt() { t2.join(); } -template -struct test_performance { - template - static void start() { - test_performance

::template start(); - test_prod_cons(); - } -}; - -template -struct test_performance<1, C, V> { - template - static void start() { - test_performance<1, C - 1, V>::template start(); - test_prod_cons(); - } -}; - -template -struct test_performance { - template - static void start() { - test_performance

::template start(); - test_prod_cons(); - } -}; - -template -struct test_performance<1, 1, V> { - template - static void start() { - test_prod_cons(); - } -}; - void Unit::test_route_performance() { - test_performance<1, 10, true>::start(); + ipc::mem::detail::static_for(std::make_index_sequence<10>{}, [](auto index) { + test_prod_cons(); + }); + test_prod_cons(); // test & verify } void Unit::test_channel() { @@ -518,9 +487,16 @@ void Unit::test_channel_rtt() { } void Unit::test_channel_performance() { - test_performance<1 , 10>::start(); - test_performance<10, 1 >::start(); - test_performance<10, 10>::start(); + ipc::mem::detail::static_for(std::make_index_sequence<10>{}, [](auto index) { + test_prod_cons(); + }); + ipc::mem::detail::static_for(std::make_index_sequence<10>{}, [](auto index) { + test_prod_cons(); + }); + ipc::mem::detail::static_for(std::make_index_sequence<10>{}, [](auto index) { + test_prod_cons(); + }); } } // internal-linkage diff --git a/test/test_mem.cpp b/test/test_mem.cpp index 6f96b3d..348c4d8 100644 --- a/test/test_mem.cpp +++ b/test/test_mem.cpp @@ -88,6 +88,7 @@ void Unit::initTestCase() { sizes__.emplace_back(static_cast(rdm())); } + ipc::mem::pool_alloc::clear(); } void Unit::cleanupTestCase() {