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?