  Fence instructions are fundamental primitives that ensure consistency in a
weakly consistent shared memory multi-core processor. The execution cost of
these instructions is significant and adds a non-trivial overhead to parallel
programs. In a naive architecture implementation, we track the ordering
constraints imposed by a fence by its entry in the reorder buffer and its
execution overhead entails stalling the processor's pipeline until the store
buffer is drained and also conservatively invalidating speculative loads. These
actions create a cascading effect of increased overhead on the execution of the
following instructions in the program. We find these actions to be overly
restrictive and that they can be further relaxed thereby allowing aggressive
optimizations.
  The current work proposes a lightweight mechanism in which we assign ordering
tags, called versions, to load and store instructions when they reside in the
load/store queues and the write buffer. The version assigned to a memory access
allows us to fully exploit the relaxation allowed by the weak consistency model
and restricts its execution in such a way that the ordering constraints by the
model are satisfied. We utilize the information captured through the assigned
versions to reduce stalls caused by waiting for the store buffer to drain and
to avoid unnecessary squashing of speculative loads, thereby minimizing the
re-execution penalty. This method is particularly effective for the release
consistency model that employs uni-directional fence instructions. We show that
this mechanism reduces the ordering instruction latency by 39.6% and improves
program performance by 11% on average over the baseline implementation.
