title: Using Boost.Lockfree queue is slower than using mutexes
body: <p>Until now I was using <code>std::queue</code> in my project. I measured the average time which a specific operation on this queue requires. </p>
  
  <p>The times were measured on 2 machines: My local Ubuntu VM and a remote server.
  Using <code>std::queue</code>, the average was almost the same on both machines: ~750 microseconds. </p>
  
  <p>Then I "upgraded" the <code>std::queue</code> to <code>boost::lockfree::spsc_queue</code>, so I could get rid of the mutexes protecting the queue. On my local VM I could see a huge performance gain, the average is now on 200 microseconds. On the remote machine however, the average went up to 800 microseconds, which is slower than it was before. </p>
  
  <p>First I thought this might be because the remote machine might not support the lock-free implementation:</p>
  
  <p>From the <a href="http://www.boost.org/doc/libs/1_59_0/doc/html/lockfree.html" rel="noreferrer">Boost.Lockfree page:</a></p>
  
  <blockquote>
    <p>Not all hardware supports the same set of atomic instructions. If it is not available in hardware, it can be emulated in software using guards. However this has the obvious drawback of losing the lock-free property.</p>
  </blockquote>
  
  <p>To find out if these instructions are supported, <code>boost::lockfree::queue</code> has a method called <code>bool is_lock_free(void) const;</code>. 
  However, <code>boost::lockfree::spsc_queue</code> does not have a function like this, which, for me, implies that it does not rely on the hardware and that is is always lockfree - on any machine. </p>
  
  <p>What could be the reason for the performance loss?</p>
  
  <hr>
  
  <h1>Exmple code (Producer/Consumer)</h1>
  
  <pre><code>// c++11 compiler and boost library required
  
  #include &lt;iostream&gt;
  #include &lt;cstdlib&gt;
  #include &lt;chrono&gt;
  #include &lt;async&gt;
  #include &lt;thread&gt;
  /* Using blocking queue:
   * #include &lt;mutex&gt;
   * #include &lt;queue&gt;
   */
  #include &lt;boost/lockfree/spsc_queue.hpp&gt;
  
  
  boost::lockfree::spsc_queue&lt;int, boost::lockfree::capacity&lt;1024&gt;&gt; queue;
  
  /* Using blocking queue:
   * std::queue&lt;int&gt; queue;
   * std::mutex mutex;
   */
  
  int main()
  {
      auto producer = std::async(std::launch::async, [queue /*,mutex*/]() 
      {
          // Producing data in a random interval
          while(true)
          {
              /* Using the blocking queue, the mutex must be locked here.
               * mutex.lock();
               */
  
              // Push random int (0-9999)
              queue.push(std::rand() % 10000);
  
              /* Using the blocking queue, the mutex must be unlocked here.
               * mutex.unlock();
               */
  
              // Sleep for random duration (0-999 microseconds)
              std::this_thread::sleep_for(std::chrono::microseconds(rand() % 1000));
          }
      }
  
      auto consumer = std::async(std::launch::async, [queue /*,mutex*/]() 
      {
          // Example operation on the queue.
          // Checks if 1234 was generated by the producer, returns if found.
  
          while(true)
          {
              /* Using the blocking queue, the mutex must be locked here.
               * mutex.lock();
               */
  
              int value;
              while(queue.pop(value)
              {
                  if(value == 1234)
                      return;
              }
  
              /* Using the blocking queue, the mutex must be unlocked here.
               * mutex.unlock();
               */
  
              // Sleep for 100 microseconds
              std::this_thread::sleep_for(std::chrono::microseconds(100));
          }
      }
  
      consumer.get();
      std::cout &lt;&lt; "1234 was generated!" &lt;&lt; std::endl;
      return 0;
  }
  </code></pre>