首页 > 解决方案 > 我们是否保证任何原子写入都会立即将原子变量的新值存储在主存储器中?

问题描述

所以,我阅读了很多关于指令和内存重新排序以及我们如何防止它的内容,但我仍然没有回答一个问题(可能是因为我不够专心)。我的问题是:我们是否保证任何原子写入都会立即将原子变量的新值存储在主存储器中?我们来看一个小例子:

std::atomic<bool> x;
std::atomic<bool> y;
std::atomic<int> count;
void WritingValues()
{
   x.store(true, std::memory_order_relaxed);
   y.store(true, std::memory_order_relaxed);
}
void ReadValues()
{
   while( !y.load(std::memory_order_relaxed) );
   if( x.load(std::memory_order_relaxed) )
       ++count;
}
int main()
{
   x = false;
   y = false;
   count = 0;
   std::thread tA(WritingValues);
   std::thread tB(ReadValues);
   tA.join();
   tB.join();
   assert( count.load() != 0 );
}

所以,在这里我们的断言肯定可以触发,因为我们使用std::memory_order_relaxed并且不阻止任何指令重新排序(或编译时的内存重新排序,我想这是同一件事)。但是如果我们在 WritingValues 中设置一些编译器屏障来防止指令重新排序,一切都会好吗?我的意思是,x.store(true, std::memory_order_relaxed) 是否保证该特定原子变量的写入将直接进入内存,没有任何延迟?还是x.load(std::memory_order_relaxed)保证该值将从内存中读取,而不是从具有无效值的缓存中读取?也就是说,本店只保证操作的原子性并具有与通常的非原子变量相同的内存行为,或者它也对内存行为有影响?

标签: c++cpu-cachememory-modelstdatomicinstruction-reordering

解决方案


 I mean, does x.store(true, std::memory_order_relaxed) guarantees, that the  
 of that particular atomic variable will be directly into the memory,  
 without any latency?  

不,它没有,事实上,如果你只读取一次布尔值和内存顺序,则没有“无效”值,真假都可以。
由于宽松的内存顺序明确保留,因此不执行任何排序。基本上,在您的情况下,它仅意味着在从 false 翻转为 true 后,在某些时候它将对所有其他进程变为 true,但并未说明“何时”会发生。所以在这里你唯一可以确定的是,它在变为真实后不会再次变为虚假。但是对于在另一个线程中它将为假多长时间没有限制。
它还保证您不会在另一个线程中看到任何部分写入的变量,但布尔值几乎不是这种情况。
您需要在这里使用 aquire 和 release。即使这样也不能保证实际内存本身,只能保证程序的行为,即使没有将数据反弹到内存中,缓存同步也可以做到这一点。


推荐阅读