Barriers and synchronization points with non-atomic variables - data race?
up vote
6
down vote
favorite
Consider the following program:
int i{0};
std::experimental::barrier b{2};
int main()
{
std::thread t0{ {
b.arrive_and_wait();
std::cout << i << 'n';
}};
std::thread t1{ {
i = 2;
b.arrive_and_wait();
}};
t0.join();
t1.join();
}
Is this program guaranteed to print out 2
, even though i
is not an atomic variable?
According to cppreference:
Calls to
arrive_and_wait
synchronizes with the start of the completion phase of the barrier. The completion of the completion phase synchronizes with the return from the call.
Calls to
arrive_and_drop
andarrive_and_wait
never introduce data races with themselves or each other.
This suggests that there is a synchronization point on each arrive_and_wait
call. However I am not sure if the compiler is allowed to reorder the read/write operations on i
, since it is non-atomic.
c++ multithreading concurrency language-lawyer barrier
add a comment |
up vote
6
down vote
favorite
Consider the following program:
int i{0};
std::experimental::barrier b{2};
int main()
{
std::thread t0{ {
b.arrive_and_wait();
std::cout << i << 'n';
}};
std::thread t1{ {
i = 2;
b.arrive_and_wait();
}};
t0.join();
t1.join();
}
Is this program guaranteed to print out 2
, even though i
is not an atomic variable?
According to cppreference:
Calls to
arrive_and_wait
synchronizes with the start of the completion phase of the barrier. The completion of the completion phase synchronizes with the return from the call.
Calls to
arrive_and_drop
andarrive_and_wait
never introduce data races with themselves or each other.
This suggests that there is a synchronization point on each arrive_and_wait
call. However I am not sure if the compiler is allowed to reorder the read/write operations on i
, since it is non-atomic.
c++ multithreading concurrency language-lawyer barrier
4
Bartop is right.. "Calls toarrive_and_wait()
synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2
) inter-thead happen before statements that are sequenced after B (cout << i
). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads.
– LWimsey
Nov 21 at 7:55
add a comment |
up vote
6
down vote
favorite
up vote
6
down vote
favorite
Consider the following program:
int i{0};
std::experimental::barrier b{2};
int main()
{
std::thread t0{ {
b.arrive_and_wait();
std::cout << i << 'n';
}};
std::thread t1{ {
i = 2;
b.arrive_and_wait();
}};
t0.join();
t1.join();
}
Is this program guaranteed to print out 2
, even though i
is not an atomic variable?
According to cppreference:
Calls to
arrive_and_wait
synchronizes with the start of the completion phase of the barrier. The completion of the completion phase synchronizes with the return from the call.
Calls to
arrive_and_drop
andarrive_and_wait
never introduce data races with themselves or each other.
This suggests that there is a synchronization point on each arrive_and_wait
call. However I am not sure if the compiler is allowed to reorder the read/write operations on i
, since it is non-atomic.
c++ multithreading concurrency language-lawyer barrier
Consider the following program:
int i{0};
std::experimental::barrier b{2};
int main()
{
std::thread t0{ {
b.arrive_and_wait();
std::cout << i << 'n';
}};
std::thread t1{ {
i = 2;
b.arrive_and_wait();
}};
t0.join();
t1.join();
}
Is this program guaranteed to print out 2
, even though i
is not an atomic variable?
According to cppreference:
Calls to
arrive_and_wait
synchronizes with the start of the completion phase of the barrier. The completion of the completion phase synchronizes with the return from the call.
Calls to
arrive_and_drop
andarrive_and_wait
never introduce data races with themselves or each other.
This suggests that there is a synchronization point on each arrive_and_wait
call. However I am not sure if the compiler is allowed to reorder the read/write operations on i
, since it is non-atomic.
c++ multithreading concurrency language-lawyer barrier
c++ multithreading concurrency language-lawyer barrier
asked Nov 20 at 11:06
Vittorio Romeo
56.1k17149289
56.1k17149289
4
Bartop is right.. "Calls toarrive_and_wait()
synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2
) inter-thead happen before statements that are sequenced after B (cout << i
). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads.
– LWimsey
Nov 21 at 7:55
add a comment |
4
Bartop is right.. "Calls toarrive_and_wait()
synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2
) inter-thead happen before statements that are sequenced after B (cout << i
). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads.
– LWimsey
Nov 21 at 7:55
4
4
Bartop is right.. "Calls to
arrive_and_wait()
synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2
) inter-thead happen before statements that are sequenced after B (cout << i
). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads.– LWimsey
Nov 21 at 7:55
Bartop is right.. "Calls to
arrive_and_wait()
synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2
) inter-thead happen before statements that are sequenced after B (cout << i
). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads.– LWimsey
Nov 21 at 7:55
add a comment |
1 Answer
1
active
oldest
votes
up vote
3
down vote
From what I understand from std::barrier reference(my emphasis) :
A barrier has a completion phase, which is executed by one of the participating threads once all threads in the set of participating threads arrive at the synchronization point. The arrive_and_wait and arrive_and_drop calls synchronize with the start of the completion phase; the end of the completion phase synchronizes with the returns from all calls blocked by its completion.
you can assume that all changes made before barrier in different threads are visible in other threads, even if they are not not atomic. As this reference points out (my emphasis):
Between threads, evaluation A inter-thread happens before evaluation B if any of the following is true
1) A synchronizes-with B
2) A is dependency-ordered before B
3) A synchronizes-with some evaluation X, and X is sequenced-before B
4) A is sequenced-before some evaluation X, and X inter-thread happens-before B
5) A inter-thread happens-before some evaluation X, and X inter-thread happens-before B
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53391637%2fbarriers-and-synchronization-points-with-non-atomic-variables-data-race%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
From what I understand from std::barrier reference(my emphasis) :
A barrier has a completion phase, which is executed by one of the participating threads once all threads in the set of participating threads arrive at the synchronization point. The arrive_and_wait and arrive_and_drop calls synchronize with the start of the completion phase; the end of the completion phase synchronizes with the returns from all calls blocked by its completion.
you can assume that all changes made before barrier in different threads are visible in other threads, even if they are not not atomic. As this reference points out (my emphasis):
Between threads, evaluation A inter-thread happens before evaluation B if any of the following is true
1) A synchronizes-with B
2) A is dependency-ordered before B
3) A synchronizes-with some evaluation X, and X is sequenced-before B
4) A is sequenced-before some evaluation X, and X inter-thread happens-before B
5) A inter-thread happens-before some evaluation X, and X inter-thread happens-before B
add a comment |
up vote
3
down vote
From what I understand from std::barrier reference(my emphasis) :
A barrier has a completion phase, which is executed by one of the participating threads once all threads in the set of participating threads arrive at the synchronization point. The arrive_and_wait and arrive_and_drop calls synchronize with the start of the completion phase; the end of the completion phase synchronizes with the returns from all calls blocked by its completion.
you can assume that all changes made before barrier in different threads are visible in other threads, even if they are not not atomic. As this reference points out (my emphasis):
Between threads, evaluation A inter-thread happens before evaluation B if any of the following is true
1) A synchronizes-with B
2) A is dependency-ordered before B
3) A synchronizes-with some evaluation X, and X is sequenced-before B
4) A is sequenced-before some evaluation X, and X inter-thread happens-before B
5) A inter-thread happens-before some evaluation X, and X inter-thread happens-before B
add a comment |
up vote
3
down vote
up vote
3
down vote
From what I understand from std::barrier reference(my emphasis) :
A barrier has a completion phase, which is executed by one of the participating threads once all threads in the set of participating threads arrive at the synchronization point. The arrive_and_wait and arrive_and_drop calls synchronize with the start of the completion phase; the end of the completion phase synchronizes with the returns from all calls blocked by its completion.
you can assume that all changes made before barrier in different threads are visible in other threads, even if they are not not atomic. As this reference points out (my emphasis):
Between threads, evaluation A inter-thread happens before evaluation B if any of the following is true
1) A synchronizes-with B
2) A is dependency-ordered before B
3) A synchronizes-with some evaluation X, and X is sequenced-before B
4) A is sequenced-before some evaluation X, and X inter-thread happens-before B
5) A inter-thread happens-before some evaluation X, and X inter-thread happens-before B
From what I understand from std::barrier reference(my emphasis) :
A barrier has a completion phase, which is executed by one of the participating threads once all threads in the set of participating threads arrive at the synchronization point. The arrive_and_wait and arrive_and_drop calls synchronize with the start of the completion phase; the end of the completion phase synchronizes with the returns from all calls blocked by its completion.
you can assume that all changes made before barrier in different threads are visible in other threads, even if they are not not atomic. As this reference points out (my emphasis):
Between threads, evaluation A inter-thread happens before evaluation B if any of the following is true
1) A synchronizes-with B
2) A is dependency-ordered before B
3) A synchronizes-with some evaluation X, and X is sequenced-before B
4) A is sequenced-before some evaluation X, and X inter-thread happens-before B
5) A inter-thread happens-before some evaluation X, and X inter-thread happens-before B
answered Nov 20 at 11:31
bartop
2,526825
2,526825
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53391637%2fbarriers-and-synchronization-points-with-non-atomic-variables-data-race%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
4
Bartop is right.. "Calls to
arrive_and_wait()
synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2
) inter-thead happen before statements that are sequenced after B (cout << i
). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads.– LWimsey
Nov 21 at 7:55