From 294df85c1d892fd2c4291310cf58aad5bf3a4e42 Mon Sep 17 00:00:00 2001 From: Coldwings Date: Wed, 31 Jan 2024 15:40:23 +0800 Subject: [PATCH] Improve heave load performance in `RingChannel` Signed-off-by: Coldwings --- common/lockfree_queue.h | 19 +++++++++++++------ thread/test/CMakeLists.txt | 4 ++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/common/lockfree_queue.h b/common/lockfree_queue.h index ea288396..5713d6fa 100644 --- a/common/lockfree_queue.h +++ b/common/lockfree_queue.h @@ -568,7 +568,7 @@ class RingChannel : public QueueType { * parameter DEFAULT_BUSY_YIELD_TIMEOUT. Ring Channel will try busy yield * in `busy_yield_timeout` usecs. */ - RingChannel(uint64_t busy_yield_turn = 64, + RingChannel(uint64_t busy_yield_turn = -1UL, uint64_t busy_yield_timeout = 1024) : m_busy_yield_turn(busy_yield_turn), m_busy_yield_timeout(busy_yield_timeout) {} @@ -576,22 +576,29 @@ class RingChannel : public QueueType { template void send(const T& x) { while (!push(x)) { - if (!full()) Pause::pause(); + Pause::pause(); } queue_sem.signal(idler.load(std::memory_order_acquire)); } T recv() { T x; - Timeout yield_timeout(m_busy_yield_timeout); - int yield_turn = m_busy_yield_turn; + if (pop(x)) return x; + // yield once if failed, so photon::now will be update + photon::thread_yield(); idler.fetch_add(1, std::memory_order_acq_rel); DEFER(idler.fetch_sub(1, std::memory_order_acq_rel)); + Timeout yield_timeout(m_busy_yield_timeout); + uint64_t yield_turn = m_busy_yield_turn; while (!pop(x)) { - if (yield_turn > 0 && photon::now < yield_timeout.expiration()) { + if (yield_turn > 0 && !yield_timeout.expired()) { yield_turn--; photon::thread_yield(); } else { - queue_sem.wait(1); + // wait for 100ms + queue_sem.wait(1, 100UL * 1000); + // reset yield mark and set into busy wait + yield_turn = m_busy_yield_turn; + yield_timeout.timeout(m_busy_yield_timeout); } } return x; diff --git a/thread/test/CMakeLists.txt b/thread/test/CMakeLists.txt index 9311430e..a8cec41f 100644 --- a/thread/test/CMakeLists.txt +++ b/thread/test/CMakeLists.txt @@ -4,6 +4,10 @@ add_executable(perf_usleepdefer_semaphore perf_usleepdefer_semaphore.cpp) target_link_libraries(perf_usleepdefer_semaphore PRIVATE photon_shared) add_test(NAME perf_usleepdefer_semaphore COMMAND $) +add_executable(perf_workpool perf_workpool.cpp) +target_link_libraries(perf_workpool PRIVATE photon_shared) +add_test(NAME perf_workpool COMMAND $) + add_executable(test-thread test.cpp x.cpp) target_link_libraries(test-thread PRIVATE photon_static) add_test(NAME test-thread COMMAND $)