update performence data; add implementation of pool_alloc::clear

This commit is contained in:
mutouyun 2019-01-02 11:58:55 +08:00
parent 33017b80fc
commit 2e26176234
9 changed files with 79 additions and 135 deletions

View File

@ -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

BIN
performence.xlsx Normal file

Binary file not shown.

View File

@ -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_);

View File

@ -26,17 +26,22 @@ constexpr decltype(auto) static_switch(std::size_t i, std::index_sequence<N, I..
static_switch(i, std::index_sequence<I...>{}, f, def);
}
template <typename F, std::size_t...I>
constexpr void static_for(std::index_sequence<I...>, F&& f) {
[[maybe_unused]] auto expand = { (f(std::integral_constant<size_t, I>{}), 0)... };
}
template <std::size_t Size>
auto& fixed() {
static synchronized<fixed_pool<Size>> pool;
return pool;
}
template <typename F>
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<
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 ,
@ -45,15 +50,26 @@ decltype(auto) choose(std::size_t size, F&& f) {
base_size * 11, base_size * 12,
base_size * 13, base_size * 14,
base_size * 15, base_size * 16
>{}, [&f](auto index) {
>;
template <typename F>
decltype(auto) choose(std::size_t size, F&& f) {
size = ((size - 1) & (~(base_size - 1))) + base_size;
return detail::static_switch(size, fixed_sequence_t {
}, [&f](auto index) {
return f(fixed<decltype(index)::value>());
}, [&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<decltype(index)::value>().clear();
});
}
static void* alloc(std::size_t size) {
return choose(size, [size](auto&& fp) { return fp.alloc(size); });

View File

@ -6,6 +6,7 @@
#include <shared_mutex>
#include <tuple>
#include <map>
#include <vector>
#include <functional>
#include <utility>
#include <cstddef>
@ -80,6 +81,18 @@ public:
}
}
void clear() {
auto guard = std::unique_lock { lc_ };
std::vector<alloc_policy*> 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);
}
};

View File

@ -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)

View File

@ -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 <int P, int C>
struct test_performance {
static void start() {
test_performance<P - 1, C - 1>::start();
test_prod_cons<P, C, false>();
}
};
template <int C>
struct test_performance<1, C> {
static void start() {
test_performance<1, C - 1>::start();
test_prod_cons<1, C, false>();
}
};
template <int P>
struct test_performance<P, 1> {
static void start() {
test_performance<P - 1, 1>::start();
test_prod_cons<P, 1, false>();
}
};
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<msg_t>*)nullptr);
benchmark_prod_cons<1, 2, LoopCount>((ipc::circ::queue<msg_t>*)nullptr);
benchmark_prod_cons<1, 4, LoopCount>((ipc::circ::queue<msg_t>*)nullptr);
benchmark_prod_cons<1, 8, LoopCount>((ipc::circ::queue<msg_t>*)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<msg_t>*)nullptr);
});
}
} // internal-linkage

View File

@ -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 <int P, int C, bool V = false>
struct test_performance {
template <typename T = ipc::route>
static void start() {
test_performance<P - 1, C - 1, V>::template start<T>();
test_prod_cons<T, P, C, V>();
}
};
template <int C, bool V>
struct test_performance<1, C, V> {
template <typename T = ipc::route>
static void start() {
test_performance<1, C - 1, V>::template start<T>();
test_prod_cons<T, 1, C, V>();
}
};
template <int P, bool V>
struct test_performance<P, 1, V> {
template <typename T = ipc::route>
static void start() {
test_performance<P - 1, 1, V>::template start<T>();
test_prod_cons<T, P, 1, V>();
}
};
template <bool V>
struct test_performance<1, 1, V> {
template <typename T = ipc::route>
static void start() {
test_prod_cons<T, 1, 1, V>();
}
};
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<ipc::route, 1, decltype(index)::value + 1, false>();
});
test_prod_cons<ipc::route, 1, 10>(); // 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<ipc::channel>();
test_performance<10, 1 >::start<ipc::channel>();
test_performance<10, 10>::start<ipc::channel>();
ipc::mem::detail::static_for(std::make_index_sequence<10>{}, [](auto index) {
test_prod_cons<ipc::channel, 1, decltype(index)::value + 1, false>();
});
ipc::mem::detail::static_for(std::make_index_sequence<10>{}, [](auto index) {
test_prod_cons<ipc::channel, decltype(index)::value + 1, 1, false>();
});
ipc::mem::detail::static_for(std::make_index_sequence<10>{}, [](auto index) {
test_prod_cons<ipc::channel, decltype(index)::value + 1,
decltype(index)::value + 1, false>();
});
}
} // internal-linkage

View File

@ -88,6 +88,7 @@ void Unit::initTestCase() {
sizes__.emplace_back(static_cast<std::size_t>(rdm()));
}
ipc::mem::pool_alloc::clear();
}
void Unit::cleanupTestCase() {