There is a RequestQueue request queue class:

 QQueue<Request> _requests; QAtomicInt _locker; void RequestQueue::enqueue(const Request &request) { while(_locker.testAndSetOrdered(0,1) == false) QThread::yieldCurrentThread(); _requests.enqueue(request); _locker = 0; } Request RequestQueue::dequeue() { forever { if(_locker.testAndSetOrdered(0,1) == true) { if(_requests.isEmpty() == true) { _locker = 0; break; } const Request request = _requests.dequeue(); _locker = 0; return request; } QThread::yieldCurrentThread(); } return Request(); } 

I decided to try the implementation without mutexes, since there are a lot of threads competing with each other, both on writing to the queue and reading from it, and I wanted to get the maximum possible acceleration.

The code works correctly, but it is confusing to not understand which method should be used for test-and-set . In the example above, this is QAtomicInteger::testAndSetOrdered() , but why not use, say, QAtomicInteger::testAndSetRelaxed() or another one of the other two remaining options instead.

Help is not very verbose about this (however, I admit that I just translate incorrectly):

QAtomicInteger provides for at-test-and-set, fetch-and-store, and fetch-and-add functions. Each implementation defines a sequence of ordering instructions. Since it’s out of the order of execution and memory ordering, it’s necessary to ensure that your application rules for all processors.

Which of the variants of memory ordering may be preferable for choosing specifically in the situation with an example from my question?

  • 3
    This is a complex topic on which you can write a lot. In short: use testAndSetOrdered until you clearly understand what works and how. Or even forget about such low-level optimizations. I wrote about this (not Qt, but the essence of one) article: one , two and three . Reading all three will help clarify the issue a bit, I hope - ixSci
  • @ixSci, thanks, I will surely read. - alexis031182
  • @ixSci, m-yes, the topic is at least a very long study, but it's worth it. The answer to my question in your articles is available. But could you clarify one thing? It turns out that this implementation with ordered-blocking is in my example, because it is essentially no better than using a regular mutex, right? - alexis031182
  • one
    By correctness, I can not say anything, but in fact, this is the usual spin-lock, which is part of any self-respecting mutex, before switching to kernel mode. I would try different mutexes (standard, boost, Qty) if there are performance problems and would choose the best one. Perhaps a shared mutex would suit you when many readers can simultaneously enter a critical section. - ixSci

0