Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I want to conclude the answer given by <strong>greyfade</strong>, which is based on <a href="http://www.drdobbs.com/high-performance-computing/212201163" rel="nofollow noreferrer">http://www.drdobbs.com/high-performance-computing/212201163</a> (the last part of the article), the optimized code would be <em>(with some modification to suit my naming and coding convention)</em> : ` </p> <pre><code>template &lt;typename T&gt; class LFQueue { private: struct LFQNode { LFQNode( T* val ) : value(val), next(nullptr) { } T* value; AtomicPtr&lt;LFQNode&gt; next; char pad[CACHE_LINE_SIZE - sizeof(T*) - sizeof(AtomicPtr&lt;LFQNode&gt;)]; }; char pad0[CACHE_LINE_SIZE]; LFQNode* first; // for one consumer at a time char pad1[CACHE_LINE_SIZE - sizeof(LFQNode*)]; InterlockedFlag consumerLock; // shared among consumers char pad2[CACHE_LINE_SIZE - sizeof(InterlockedFlag)]; LFQNode* last; // for one producer at a time char pad3[CACHE_LINE_SIZE - sizeof(LFQNode*)]; InterlockedFlag producerLock; // shared among producers char pad4[CACHE_LINE_SIZE - sizeof(InterlockedFlag)]; public: LFQueue() { first = last = new LFQNode( nullptr ); // no more divider producerLock = consumerLock = false; } ~LFQueue() { while( first != nullptr ) { LFQNode* tmp = first; first = tmp-&gt;next; delete tmp; } } bool pop( T&amp; result ) { while( consumerLock.set(true) ) { } // acquire exclusivity if( first-&gt;next != nullptr ) { // if queue is nonempty LFQNode* oldFirst = first; first = first-&gt;next; T* value = first-&gt;value; // take it out first-&gt;value = nullptr; // of the Node consumerLock = false; // release exclusivity result = *value; // now copy it back delete value; // and clean up delete oldFirst; // both allocations return true; // and report success } consumerLock = false; // release exclusivity return false; // queue was empty } bool push( const T&amp; t ) { LFQNode* tmp = new LFQNode( t ); // do work off to the side while( producerLock.set(true) ) { } // acquire exclusivity last-&gt;next = tmp; // A: publish the new item last = tmp; // B: not "last-&gt;next" producerLock = false; // release exclusivity return true; } }; </code></pre> <p>`</p> <p>another question is how do you define CACHE_LINE_SIZE? its vary on ever CPUs right?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload