optimize channel performance

This commit is contained in:
mutouyun 2018-12-29 12:12:27 +08:00
parent 02a5920697
commit 812d4b3be5
4 changed files with 39 additions and 23 deletions

View File

@ -46,17 +46,17 @@ UT & benchmark test function, see: [test](test)
| PROD-CONS: N-M | DATAS: Random 2-256bits * 100000 | | PROD-CONS: N-M | DATAS: Random 2-256bits * 100000 |
| ------ | ------ | | ------ | ------ |
| `RTT` | `276.056 ms, 2.76056 us/d` | | `RTT` | `228.383 ms, 2.28383 us/d` |
| `1-1` | `145.875 ms, 1.45875 us/d` | | `1-1` | `144.371 ms, 1.44371 us/d` |
| `1-2` | `298.616 ms, 2.98616 us/d` | | `1-2` | `249.874 ms, 2.49874 us/d` |
| `1-4` | `633.239 ms, 6.33239 us/d` | | `1-4` | `525.721 ms, 5.25721 us/d` |
| `1-8` | `1113.56 ms, 11.1356 us/d` | | `1-8` | `729.373 ms, 7.29373 us/d` |
| `2-1` | `459.178 ms, 2.29589 us/d` | | `2-1` | `311.176 ms, 1.55588 us/d` |
| `4-1` | `768.695 ms, 1.92174 us/d` | | `4-1` | `744.733 ms, 1.86183 us/d` |
| `8-1` | `1820.28 ms, 2.27535 us/d` | | `8-1` | `1819.54 ms, 2.27442 us/d` |
| `2-2` | `576.380 ms, 2.88190 us/d` | | `2-2` | `573.536 ms, 2.86768 us/d` |
| `4-4` | `2060.98 ms, 5.15245 us/d` | | `4-4` | `1629.51 ms, 4.07378 us/d` |
| `8-8` | `7355.66 ms, 9.19458 us/d` | | `8-8` | `6336.53 ms, 7.92066 us/d` |
## Reference ## Reference

View File

@ -56,6 +56,7 @@ public:
std::string n_; std::string n_;
std::size_t id_; std::size_t id_;
bool marked_ = false;
std::array<route, id_pool::max_count> rts_; std::array<route, id_pool::max_count> rts_;
@ -66,6 +67,18 @@ public:
auto& acc() { auto& acc() {
return info().ch_acc_; return info().ch_acc_;
} }
void mark_id() {
if (marked_) return;
marked_ = true;
[[maybe_unused]] auto guard = std::unique_lock { info().lc_ };
acc().mark_acquired(id_);
}
auto& sender() {
mark_id();
return r_;
}
}; };
channel::channel() channel::channel()
@ -117,7 +130,7 @@ bool channel::connect(char const * name) {
return false; return false;
} }
{ {
std::unique_lock<rw_lock> guard { impl(p_)->info().lc_ }; [[maybe_unused]] auto guard = std::unique_lock { impl(p_)->info().lc_ };
if (impl(p_)->acc().invalid()) { if (impl(p_)->acc().invalid()) {
impl(p_)->acc().init(); impl(p_)->acc().init();
} }
@ -133,7 +146,7 @@ bool channel::connect(char const * name) {
void channel::disconnect() { void channel::disconnect() {
if (!valid()) return; if (!valid()) return;
{ {
std::unique_lock<rw_lock> guard { impl(p_)->info().lc_ }; [[maybe_unused]] auto guard = std::unique_lock { impl(p_)->info().lc_ };
impl(p_)->acc().release(impl(p_)->id_); impl(p_)->acc().release(impl(p_)->id_);
} }
for (auto& rt : impl(p_)->rts_) { for (auto& rt : impl(p_)->rts_) {
@ -148,7 +161,7 @@ std::size_t channel::recv_count() const {
} }
bool channel::wait_for_recv(std::size_t r_count, std::size_t until) const { bool channel::wait_for_recv(std::size_t r_count, std::size_t until) const {
return ::wait_for_recv(impl(p_)->r_, r_count, until); return ::wait_for_recv(impl(p_)->sender(), r_count, until);
} }
bool channel::wait_for_recv(std::size_t r_count) const { bool channel::wait_for_recv(std::size_t r_count) const {
@ -156,27 +169,27 @@ bool channel::wait_for_recv(std::size_t r_count) const {
} }
bool channel::send(void const * data, std::size_t size) { bool channel::send(void const * data, std::size_t size) {
return impl(p_)->r_.send(data, size); return impl(p_)->sender().send(data, size);
} }
bool channel::send(buff_t const & buff) { bool channel::send(buff_t const & buff) {
return impl(p_)->r_.send(buff); return impl(p_)->sender().send(buff);
} }
bool channel::send(std::string const & str) { bool channel::send(std::string const & str) {
return impl(p_)->r_.send(str); return impl(p_)->sender().send(str);
} }
bool channel::send_for(std::size_t r_count, void const * data, std::size_t size) { bool channel::send_for(std::size_t r_count, void const * data, std::size_t size) {
return ::channel_send(impl(p_)->r_, r_count, data, size); return ::channel_send(impl(p_)->sender(), r_count, data, size);
} }
bool channel::send_for(std::size_t r_count, buff_t const & buff) { bool channel::send_for(std::size_t r_count, buff_t const & buff) {
return ::channel_send(impl(p_)->r_, r_count, buff); return ::channel_send(impl(p_)->sender(), r_count, buff);
} }
bool channel::send_for(std::size_t r_count, std::string const & str) { bool channel::send_for(std::size_t r_count, std::string const & str) {
return ::channel_send(impl(p_)->r_, r_count, str); return ::channel_send(impl(p_)->sender(), r_count, str);
} }
buff_t channel::recv() { buff_t channel::recv() {
@ -187,7 +200,7 @@ buff_t channel::recv() {
std::size_t counter = 0; std::size_t counter = 0;
// get all acquired ids // get all acquired ids
{ {
std::shared_lock<rw_lock> guard { impl(p_)->info().lc_ }; [[maybe_unused]] auto guard = std::shared_lock { impl(p_)->info().lc_ };
impl(p_)->acc().for_acquired([this, &acqs, &counter](std::size_t id) { impl(p_)->acc().for_acquired([this, &acqs, &counter](std::size_t id) {
if (id == impl(p_)->id_) return; if (id == impl(p_)->id_) return;
acqs[counter++] = id; acqs[counter++] = id;

View File

@ -38,9 +38,12 @@ public:
} }
std::size_t id = cursor_; std::size_t id = cursor_;
cursor_ = next_[id]; // point to next cursor_ = next_[id]; // point to next
return id;
}
void mark_acquired(std::size_t id) {
next_[id] = acquir_; next_[id] = acquir_;
acquir_ = static_cast<uint_t<8>>(id); // put it in acquired list acquir_ = static_cast<uint_t<8>>(id); // put it in acquired list
return id;
} }
bool release(std::size_t id) { bool release(std::size_t id) {

View File

@ -509,7 +509,7 @@ void Unit::test_channel_rtt() {
} }
void Unit::test_channel_performance() { void Unit::test_channel_performance() {
test_performance<1 , 10, true>::start<ipc::channel>(); test_performance<1 , 10>::start<ipc::channel>();
test_performance<10, 1 >::start<ipc::channel>(); test_performance<10, 1 >::start<ipc::channel>();
test_performance<10, 10>::start<ipc::channel>(); test_performance<10, 10>::start<ipc::channel>();
} }