Может ли оборудование переупорядочить атомную нагрузку с последующей атомной хранилищем, если хранилище является условным на нагрузке? It would be highly unintuitive if this could happen, because if thread1 speculatively due to branch prediction, or for whatever reason, writes y = 1 before the condition in the if statement is confirmed as true, then if it later finds out the condition resolves to false, there is no way to undo the damage (roll back the changes), because another thread may have already read the updated value of y!
Я не думаю, что выпуск и приобретение семантики поможет в этом случае. Std :: memory_order_release on y.store () будет использоваться для выполнения более ранних записей, видимых в другие потоки, которые видели значение y , но в этом случае ничто не может сделать, чтобы повлиять на видимость x в других потоках, потому что x не было написано по потоке1. Примеры, которые я видел в документации C ++ для получения семантики приобретения и выпуска только о паре потоков, где один из них является чисто автором, а другой-чисто читатель.std::atomic x;
std::atomic y;
void thread1() {
int val = x.load(std::memory_order_relaxed);
if( val == 42 ){
y.store(1, std::memory_order_relaxed);
}
}
< /code>
Изменить: меня попросили предоставить примеры, включая другие потоки. Один рассказывает о упорядочении магазинов, как воспринимается наблюдателями, в то время как другой касается возможности спекулятивного выполнения хранилищ.// This example is about ordering.
// Will thread3 see the new value of x, if thread1 has seen it?
std::atomic x;
std::atomic y;
void thread1() {
int val = x.load(std::memory_order_relaxed);
if( val == 42 ){
y.store(1, std::memory_order_relaxed);
}
}
void thread2() {
x.store(42, std::memory_order_relaxed);
}
void thread3() {
if( y.load(std::memory_order_relaxed) == 1 ){
std::atomic_thread_fence(memory_order_acquire);
int r = x.load(std::memory_order_relaxed);
assert(r == 42); // Can this go wrong?
}
}
< /code>
// Similar, but we're putting it inside a loop
// to make it a little more interesting.
// This focuses on speculative execution.
std::atomic x;
std::atomic y;
std::atomic terminate;
void thread1() {
while( !terminate.load(std::memory_order_relaxed) ){
int val = x.load(std::memory_order_relaxed);
if( val == 42 ){
// Can y.store() be done speculatively?
y.store(1, std::memory_order_relaxed);
break;
}
}
}
void thread2() {
// This will count down and write to x,
// but should never actually store the value 42.
for(int idx = 10000000; idx > 42; --idx){
x.store(idx, std::memory_order_relaxed);
}
sleep_seconds(10);
terminate = true;
}
void thread3() {
while( !terminate.load(std::memory_order_relaxed) ){
if( y.load(std::memory_order_relaxed) == 1 ){
// This should never happen!
Open_Pandoras_Box();
Launch_Nuclear_Missiles();
Unleash_Armageddon();
break;
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... f-the-stor
Может ли оборудование изменить порядок атомной нагрузки, за которой следует атомный магазин, если хранилище условно подх ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение