对于任何std::atomic<T>
其中T是一个基本类型:
如果我使用std::memory_order_acq_rel
为fetch_xxx
操作,并且std::memory_order_acquire
的load
运行std::memory_order_release
的store
经营一味(我的意思是,就像重置这些功能的默认内存排序)
- 请问结果是一样的,如果我使用
std::memory_order_seq_cst
(正在使用默认)任何声明的操作? - 如果结果是一样的,就是这个用法比使用无论如何不同
std::memory_order_seq_cst
在效率方面?
在C ++为原子操作11存储器排序参数指定所述排序约束。 如果你做一个店std::memory_order_release
,并从另一个线程的负载读取与价值std::memory_order_acquire
从第二个线程则后续读取操作将通过在此之前,是第一个线程看到存储到任何存储位置的任何值商店释放, 或更高存储于任何那些存储器位置 。
如果同时存储和后续的加载是std::memory_order_seq_cst
那么这两个线程之间的关系是相同的。 你需要更多的线程看出区别。
例如std::atomic<int>
变量x
和y
,无论最初为0。
主题1:
x.store(1,std::memory_order_release);
主题2:
y.store(1,std::memory_order_release);
主题3:
int a=x.load(std::memory_order_acquire); // x before y
int b=y.load(std::memory_order_acquire);
主题4:
int c=y.load(std::memory_order_acquire); // y before x
int d=x.load(std::memory_order_acquire);
由于写入,有商店之间没有关系x
和y
,所以它是非常有可能看到a==1
, b==0
在螺纹3,以及c==1
和d==0
在螺纹4。
如果所有的内存排序更改为std::memory_order_seq_cst
那么这可以确保对存储之间的排序x
和y
。 因此,如果线3看到a==1
和b==0
则意味着商店x
必须是商店之前y
,因此,如果线4看到c==1
,这意味着商店y
已完成,则商店x
也必须完成,所以我们必须要有d==1
。
在实践中,然后使用std::memory_order_seq_cst
到处都将增加额外的开销,要么加载或存储或两者兼而有之,这取决于你的编译器和处理器架构。 例如,用于x86处理器的常用技术是使用XCHG
指令,而不是MOV
指令std::memory_order_seq_cst
店,以提供必要的排序保证,而对于std::memory_order_release
普通MOV
就足够了。 在有更宽松的内存架构的系统开销可能更大,因为普通的加载和存储有较少的保证。
内存排序是困难的。 我专门几乎一整章给它我的书 。
内存排序可能是相当棘手,而且犯错的效果往往是非常微妙的。
与所有的存储排序,关键的一点是,它保证什么“已经发生”,没有什么事情发生。 例如,如果你存储东西几个变量(例如x = 7; y = 11;
则另一处理器可以能够看到y
为11它看到前值7
x中。 通过使用设定之间存储器排序操作x
和设置y
,所使用的处理器将保证x = 7;
已被写入到内存继续储存的东西之前y
。
大多数时候,它不是真正重要的什么顺序写的发生,只要价值最终更新。 但是,如果我们,比如说,有整数的循环缓冲区,我们这样做:
buffer[index] = 32;
index = (index + 1) % buffersize;
和一些其他的线程使用index
来确定新的值写入,那么我们就需要有32
先写,然后index
后进行更新。 否则,其他线程可能会old
数据。
这同样适用于制作的旗语,互斥这类东西的工作 - 这就是为什么条款发布和获取用于记忆障碍的类型。
现在, cst
是最严格的排序规则-它强制执行读取和编写了数据的写入出去内存处理器才可以继续做多操作。 这将是比做具体的获取或释放障碍慢。 它迫使处理器,以确保存储和加载已经完成,而不是仅仅商店或只是负载。
多大区别呢,让? 它是高度依赖于系统archiecture是什么。 在一些系统上,高速缓存需要刷新[部分],并从一个核心到另一个送往说:“如果你想继续请做这个缓存刷新工作”中断 - 这可能需要几百个周期。 在其他处理器,这只是一些很小的比例高于做一个普通的内存写入速度较慢。 X86是快速做这相当不错。 某些类型的嵌入式处理器,(某些型号 - ?不知道)ARM例如,需要更多的工作,在处理器,以确保一切正常。