Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How is the result 0 20 possible in figure 3.1 #48

Open
lucasalavapena opened this issue Jan 15, 2024 · 1 comment
Open

How is the result 0 20 possible in figure 3.1 #48

lucasalavapena opened this issue Jan 15, 2024 · 1 comment
Labels

Comments

@lucasalavapena
Copy link

lucasalavapena commented Jan 15, 2024

The content that the question is about

https://marabos.nl/atomics/memory-ordering.html#happens-before

More interestingly, the output can also be 0 20, even though there is no possible globally consistent order of the four operations that would result in this outcome. When 3 is executed, there is no happens-before relationship with 2, which means it could load either 0 or 20. When 4 is executed, there is no happens-before relationship with 1, which means it could load either 0 or 10. Given this, the output 0 20 is a valid outcome.

The question

Firstly, I want to thank you for writing this book and making it freely available online. I have been enjoying reading it. Recently, I was reading your book with a group, and almost all of us found this section somewhat difficult to understand.

Anyways to the question: How could 0 20 be possible if there are no possible globally consistent order of the four operations that would result in this outcome? I could only see it possible if instruction scheduling/reordering were allowed, which would make sense in this case since we have relaxed memory ordering. I thought with relaxed memory ordering the compiler should be able to reorder those instructions as relaxed memory ordering implies no additional dependency between the atomic memory related instructions.

However given the definition of the happens before relationship and figure 3.1, i.e. no instruction reordering within a thread:

The basic happens-before rule is that everything that happens within the same thread happens in order. If a thread is executing f(); g();, then f() happens-before g().
it causes me confusion.

The only legal states following the happens before relationship I thought would be:

  • 1, 2, 3, 4: 10 20
  • 1, 3, 2, 4: 10 0
  • 1, 3, 4, 2: 10 0
  • 3, 1, 2, 4 : 10 0
  • 3, 1, 4, 2 : 10 0
  • 3, 4, 1, 2 0 0

Also when running your provided code I get 10 20 ~ 92% of the times and the rest 0 0. Would it be possible somehow to force it to get 0 20 in this example? Perhaps a compiler flag?

Later on it does seem to be implied that this might only be the case when instruction scheduling/reordering is allowed:

Our intuitive understanding of the concept of "before" breaks down when things don’t necessarily happen in a globally consistent order, such as when instruction reordering is involved.

I am probably missing something, otherwise in my opinion it is inconsistent.

@matteosantama
Copy link

I came here looking for an answer to this same question. I also do not believe 0 20 is a possible outcome.

If (3) loads 20, then (2) was executed. And since (1) happens before (2) then (1) must have executed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants