The mfence was not in the SPSC queue implementation, but in the code
that allows wakes a potentially sleeping MPSC consumer.
producer_idx.store(..., memory_order_release)
if (consumer_is_sleeping) wake_it_up()
an mfence (or a clever trick) is required between these two lines.
On 03/19/2018 04:41 PM, Dan Eloff wrote:
We're getting a little confused on the terminology. That's a compiler
barrier, as it prevents the compiler from reordering certain
instructions beyond it (I don't think relaxed prevents any reordering,
but release and acquire do.) I know you understand this stuff given
your background, I just want to clarify the terminology for the sake
of the discussion.
The original post and article discuss real memory barriers like
mfence. These prevent the CPU from reordering loads and stores. Which
should be unnecessary for SPSC queues on x86 because it gives strong
enough guarantees about reordering, in this case, without that.
On Mon, Mar 19, 2018, 1:19 AM Avi Kivity <[email protected]
<mailto:[email protected]>> wrote:
The release write is a memory barrier. It's not an SFENCE or
another fancy instruction, but it is a memory barrier from the
application writer's point of view.
The C++ code
x.store(5, std::memory_order_relaxed)
has two effects on x86:
1. generate a write to x that is a single instruction (e.g. mov
$5, x)
2. prevent preceding writes from being reordered by the compiler
(they are implicitly ordered by the processor on x86).
On 03/18/2018 08:16 PM, Dan Eloff wrote:
You don't need memory barriers to implement an SPSC queue for
x86. You can do a relaxed store to the queue followed by a
release write to producer_idx. As long as consumer begins with an
acquire load from producer_idx it is guaranteed to see all stores
to the queue memory before producer_idx, according to the happens
before ordering. There are no memory barriers on x86 for
acquire/release semantics.
The release/acquire semantics have no meaning when used with
different memory locations, but if used on producer_idx when
synchronizing the consumer, and consumer_idx when synchronizing
the producer, it should work.
On Thu, Feb 15, 2018 at 8:29 AM, Avi Kivity <[email protected]
<mailto:[email protected]>> wrote:
Ever see mfence (aka full memory barrier, or
std::memory_order_seq_cst) taking the top row in a profile?
Here's the complicated story of how we took it down:
https://www.scylladb.com/2018/02/15/memory-barriers-seastar-linux/
--
You received this message because you are subscribed to the
Google Groups "mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from
it, send an email to
[email protected]
<mailto:mechanical-sympathy%[email protected]>.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the
Google Groups "mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to [email protected]
<mailto:[email protected]>.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google
Groups "mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected]
<mailto:[email protected]>.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.