rigtorp / MPMCQueue

A bounded multi-producer multi-consumer concurrent queue written in C++11
MIT License
1.15k stars 159 forks source link

Efficient block while pushing/popping #28

Closed Unbinilium closed 3 years ago

Unbinilium commented 3 years ago

I noticed that standard c++20 has add wait and notify function to atomic library occasionally:

Thinking that there's an empty queue, one thread got blocked in a while(!is_it_changed) loop while popping an item, it would consume many cpu resources if there is no other thread(s) enqueue an item instantly, this case as same as pushing to a full queue.

In my opinion, the thread which got blocked while dequeueing from an empty queue (or enqueueing to a full queue) is better go for "sleep" after detecting whether changes has been made to it for several times, then if there are some thread enqueued (or dequeued), it will "wake-up" the sleeping thread(s) again to detect changes, I think using this form of change-detection is often more efficient than simple polling.

Through my poor implementation seems works and passed the MPMCQueueTest with no significant performance effect, but I may not considered all the different situations in synchronizing threads. Could you have some suggestion? Thanks!

rigtorp commented 3 years ago

Yes something like this should work. You also need to notify on the head and tail counters when the queue is empty. Maybe there's a way to sometimes suppress the notify_all call.

I wrote this queue because I specifically wanted low latency, in my application using futex would be a too big performance penalty. But in most applications using futex to let waiting threads go to sleep makes sense. I think Intel TBB already has a queue like that you can use if you want to put waiting threads to sleep.

Unbinilium commented 3 years ago

Yes something like this should work. You also need to notify on the head and tail counters when the queue is empty. Maybe there's a way to sometimes suppress the notify_all call.

I wrote this queue because I specifically wanted low latency, in my application using futex would be a too big performance penalty. But in most applications using futex to let waiting threads go to sleep makes sense. I think Intel TBB already has a queue like that you can use if you want to put waiting threads to sleep.

Thanks for your suggestion, I’ll try TBB instead, closed now.