diff --git a/imperative/python/src/helper.h b/imperative/python/src/helper.h index 6a2fb1c938c6d15b2064fa11a336860397410f9a..b9f61e3d431c463c9039dab51113d4d55d8bd2e6 100644 --- a/imperative/python/src/helper.h +++ b/imperative/python/src/helper.h @@ -67,6 +67,12 @@ auto to_tuple(T begin, T end, pybind11::return_value_policy policy = pybind11::r class PyTaskDipatcher { struct Queue : mgb::AsyncQueueSC, Queue> { using Task = std::function; + + // set max_spin=0 to prevent Queue fetch task in busy wait manner. + // this won't affect throughput when python interpreter is sending enough task, + // but will significantly save CPU time when waiting for task, e.g. wait for data input + Queue() : mgb::AsyncQueueSC, Queue>(0) {} + void process_one_task(Task& f) { if (!Py_IsInitialized()) return; pybind11::gil_scoped_acquire _; diff --git a/imperative/src/impl/interpreter_impl.h b/imperative/src/impl/interpreter_impl.h index c1dd8447d77ff717d863bfa5bc381c58bc954abf..4a5e3fe9eb846a4038ebfc2f4caba61b14d2d7e8 100644 --- a/imperative/src/impl/interpreter_impl.h +++ b/imperative/src/impl/interpreter_impl.h @@ -207,7 +207,11 @@ private: size_t m_enable_evict = 0; struct WorkQueue : AsyncQueueSC { - WorkQueue(ChannelImpl* owner) : m_owner(owner) { + // set max_spin=0 to prevent Queue fetch task in busy wait manner. + // this won't affect throughput when python interpreter is sending enough task, + // but will significantly save CPU time when waiting for task, e.g. wait for data input + WorkQueue(ChannelImpl* owner) + : AsyncQueueSC(0), m_owner(owner) { sys::set_thread_name("interpreter"); } void process_one_task(Command& cmd) { diff --git a/imperative/src/impl/physical_tensor.cpp b/imperative/src/impl/physical_tensor.cpp index 19fa9a29016afa4c565eb47d05ed139ad5428e5f..b4a76626d4cbf9ca7df932a6b376f0e6f3dfeb5a 100644 --- a/imperative/src/impl/physical_tensor.cpp +++ b/imperative/src/impl/physical_tensor.cpp @@ -30,7 +30,10 @@ class AsyncReleaser : public CompNodeDepedentObject { AsyncReleaser* m_par_releaser; public: - Waiter(AsyncReleaser* releaser) : m_par_releaser(releaser) {} + // disable busy wait by set max_spin=0 to save CPU cycle + Waiter(AsyncReleaser* releaser) + : AsyncQueueSC(0), + m_par_releaser(releaser) {} void process_one_task(WaiterParam& param) { if (param.event->finished()) {