Re: out of order execution / reoredering of instructions



"junky_fellow@xxxxxxxxxxx" <junky_fellow@xxxxxxxxxxx> writes:

Richard Heathfield wrote:
junky_fellow@xxxxxxxxxxx said:


How can a C programmer, prevent the reordering of instructions by
compiler and by the CPU ?

There is something wrong in this sentence: it implies that there is an
ordering of instructions deductible from the C source. There is no such
thing. The nearest existing thing is a partial ordering on memory access.

You can enforce the program logic you want by careful use of sequence
points. From a language perspective, there is no mechanism for dictating to
the compiler how it should translate your code.

In what cases, the programmer should take care of these reorderings ?

As long as the program computes the result properly, why should we care what
order things happen in?


In a device driver code, we need to write some specific value to
the device registers in some specific sequence. If that sequence
is changed, the device may not work as desired. In such cases,
how can we prevent reordering ?

The first thing is to indicate to the compiler which objects you care
about. All access to those should be qualified as volatile (use volatile
variable or pointer to volatile) so that they are considered as observable
behavior and so can not be reordered or removed as easily.

The second thing is to understand the rules of the partial ordering. A
short version: use one access whose orderubg you care about per statement.
For a long version search about sequence points.

Even if the requirements of the standard are fussy (it at least leaves the
definition of what an access is implementation defined), these two steps
should insure that at the machine langage level all access are present (ie
that the optimiser will not delete an access it considers as redundant) and
in the correct order.

The final step is ensuring that the processor will not play tricks with
your accesses. Using memory barriers will remove some of the tricks but
not other. Notifying the processor that the memory region is used for IO
and should not be cached should be enough. If you are writing a device
driver, your OS should provide an API for that.

In a multiprocessor environment, where multiple threads may execute
parallelly on different processors, it is required that the global
variables (that multiple threads may access) may be modified in some
sequence by a particular thread. How, such can this be achieved ?

Volatile is of no use in this context as for volatile to be effective, you
need non cached memory and OS usually don't provide an API allowing
unprivileged application to have some. But in this context you have weaker
ordering constaints and while C does not provide anything which help, OS
synchronization primitives and memory barriers provides what is needed.
Ask on comp.programming.threads.

Yours,

--
Jean-Marc
.



Relevant Pages