title: How to mix atomic and non-atomic operations in C++?
body: <p>The std::atomic types allow atomic access to variables, but I would sometimes
  like non-atomic access, for example when the access is protected by a mutex.
  Consider a bitfield class that allows both multi-threaded access (via insert)
  and single-threaded vectorized access (via operator|=):</p>
  <pre><code>class Bitfield
  {
      const size_t size_, word_count_;
      std::atomic&lt;size_t&gt; * words_;
      std::mutex mutex_;
  
  public:
  
      Bitfield (size_t size) :
          size_(size),
          word_count_((size + 8 * sizeof(size_t) - 1) / (8 * sizeof(size_t)))
      {
          // make sure words are 32-byte aligned
          posix_memalign(&amp;words_, 32, word_count_ * sizeof(size_t));
          for (int i = 0; i &lt; word_count_; ++i) {
              new(words_ + i) std::atomic&lt;size_t&gt;(0);
          }
      }
      ~Bitfield () { free(words_); }
  
  private:
      void insert_one (size_t pos)
      {
          size_t mask = size_t(1) &lt;&lt; (pos % (8 * sizeof(size_t)));
          std::atomic&lt;size_t&gt; * word = words_ + pos / (8 * sizeof(size_t));
          word-&gt;fetch_or(mask, std::memory_order_relaxed);
      }
  public:
      void insert (const std::set&lt;size_t&gt; &amp; items)
      {
          std::lock_guard&lt;std::mutex&gt; lock(mutex_);
          // do some sort of muti-threaded insert, with TBB or #pragma omp
          parallel_foreach(items.begin(), items.end(), insert_one);
      }
  
      void operator |= (const Bitfield &amp; other)
      {
          assert(other.size_ == size_);
          std::unique_lock&lt;std::mutex&gt; lock1(mutex_, defer_lock);
          std::unique_lock&lt;std::mutex&gt; lock2(other.mutex_, defer_lock);
          std::lock(lock1, lock2); // edited to lock other_.mutex_ as well
          // allow gcc to autovectorize (256 bits at once with AVX)
          static_assert(sizeof(size_t) == sizeof(std::atomic&lt;size_t&gt;), &quot;fail&quot;);
          size_t * __restrict__ words = reinterpret_cast&lt;size_t *&gt;(words_);
          const size_t * __restrict__ other_words
              = reinterpret_cast&lt;const size_t *&gt;(other.words_);
          for (size_t i = 0, end = word_count_; i &lt; end; ++i) {
              words[i] |= other_words[i];
          }
      }
  };
  </code></pre>
  <p>Note operator|= is very close to what's in my real code, but insert(std::set) is
  just attempting to capture the idea that one can</p>
  <pre><code>acquire lock;
  make many atomic accesses in parallel;
  release lock;
  </code></pre>
  <p>My question is this: what is the best way to mix such atomic and non-atomic
  access?  Answers to [1,2] below suggest that casting is wrong (and I agree).  But surely the standard allows such apparently safe access?</p>
  <p>More generally, can one use a reader-writer-lock and allow &quot;readers&quot; to read and write atomically, and the unique &quot;writer&quot; to read and write non-atomically?</p>
  <h2>References</h2>
  <ol>
  <li><a href="https://stackoverflow.com/questions/8749038/how-to-use-stdatomic-efficiently">How to use std::atomic efficiently</a></li>
  <li><a href="https://stackoverflow.com/questions/7234270/accessing-atomicint-of-c0x-as-non-atomic">Accessing atomic&lt;int&gt; of C++0x as non-atomic</a></li>
  </ol>