简体   繁体   中英

Does as-if rule prevent compiler reordering of accesses to global/member variables?

I'm studying the effects that compiler optimizations (specifically, instruction reordering here) may have for a multi-threaded program.

Let's say we have a reader thread and a writer thread.

// Global shared data between threads
bool data;
bool flag = false;

// writer.cpp
void writer()
{
    data = true;  // (1)
    flag = true;  // (2)
}

// reader.cpp
void reader()
{
    if (flag)
    {
       count << data;
    }
}

May a C++11-compliant compiler reorder instruction (1) and (2)

According to C++ "as-if" rule, the transformation shouldn't change a program's observable behavior. Apparently, when compiling the writer, a compiler generally can't be sure whether reordering (1) and (2) will change the program's observable behavior or not, because data and flag are both globals which may affect another thread's observable behavior.

But it states here that this kind of reordering can happen, see memory ordering at compile time .

So do we need a compiler barrier between (1) and (2) ? (I'm well aware of possible CPU reordering. This question is only on compiler reordering)

Absolutely they may. The compiler has no obligation whatsoever to consider side effects to other threads or hardware.

The compiler is only forced to consider this if you use volatile or synchronization (and those two are not interchangable).

The Standard memory model is known as SC-DRF, or Sequentially Consistent Data Race Free. A data race would be exactly the scenario you've just described- where one thread is observing non-synchronized variables whilst another is mutating them. This is undefined behaviour. Effectively, the Standard explicitly gives the compiler the freedom to assume that there are no other threads or hardware which is reading non-volatile non-synchronized variables. It is absolutely legitimate for a compiler to optimize on that basis.

By the way, that link is kinda crap. His "fix" does not fix anything at all. The only correct fix for multi-threaded code is to use synchronization.

You have already asked this question on comp.lang.c++.moderated a week and a half ago, and you were given a complete explanation about the relationship between the C++11 requirements for sequencing within a single thread and for "happens before" relationships on synchronization between threads, here: https://groups.google.com/forum/#!topic/comp.lang.c++.moderated/43_laZwVXYg

What part of that reply didn't you understand, and we can try again?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM