0

I'm learning memory barrier so I referred to memory-barriers documentation in linux kernel source code. And there is one description that I can't understand:

Control dependencies can be a bit tricky because current compilers do not understand them. The purpose of this section is to help you prevent the compiler's ignorance from breaking your code.

A load-load control dependency requires a full read memory barrier, not simply a data dependency barrier to make it work correctly. Consider the following bit of code:

q = READ_ONCE(a);
if (q) {
  <data dependency barrier>  /* BUG: No data dependency!!! */
  p = READ_ONCE(b);
}

This will not have the desired effect because there is no actual data dependency, but rather a control dependency that the CPU may short-circuit by attempting to predict the outcome in advance, so that other CPUs see the load from b as having happened before the load from a. In such a case what's actually required is:

q = READ_ONCE(a);
if (q) {
  <read barrier>
  p = READ_ONCE(b);
}

And the following description is what confuse me:

CPU may short-circuit by attempting to predict the outcome in advance, so that other CPUs see the load from b as having happened before the load from a

Does CPU prediction have something to do with other CPUs see the load from b as having happened before the load from a? How does this happen?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
cong
  • 1,105
  • 1
  • 12
  • 29
  • 2
    Yes, speculative execution (based on branch prediction) means that control dependencies aren't like data dependencies, and later code doesn't have to wait for the branch condition. `q = READ_ONCE(a)` / `p = READ_ONCE(array[q])` would have a data dependency, like C++ memory_order_consume. – Peter Cordes Sep 26 '20 at 07:06
  • @PeterCordes, What do you mean by **later code doesn't have to wait for the branch condition**? and what's the real effect of this? – cong Sep 26 '20 at 08:10
  • @Peter Cordes, any futher explanation? – cong Sep 27 '20 at 10:57
  • @PeterCordes, does this meaning that speculative execution (based on branch prediction) will make the code just like `q = READ_ONCE(a);p = READ_ONCE(b);` and thus cause the problem of **other CPUs see the load from b as having happened before the load from a**? – cong Sep 27 '20 at 12:23
  • 1
    Yes, that's exactly what the Linux documentation is explaining. Speculative *out-of-order* execution does speculate past branches instead of waiting for the branch direction to be known. – Peter Cordes Sep 27 '20 at 16:38

0 Answers0