在C++ 0x中的一个原子变量文档中,当描述内存顺序时,它提到:
发布 - 获取订购
在强排序系统(x86,SPARC,IBM大型机)上,发布 - 获取顺序是自动的.没有为此同步模式发出额外的CPU指令,只会影响某些编译器优化...
首先是真的,x86遵循严格的内存排序?似乎效率非常低,总是强加于此.意味着每次写入和读取都有围栏?
另外,如果我在x86系统上有一个对齐的int,原子变量是否可以用于任何目的?
Ada*_*eld 11
是的,x86具有严格的内存排序,请参阅英特尔手册第3A卷第8.2章.较老的x86处理器(如386)提供了真正严格的排序(称为强排序)语义,而更现代的x86处理器在少数情况下略微放松了条件,但您无需担心.例如,当写入是高速缓存命中时(因此读取的是不同的地址),Pentium和486允许读取高速缓存未命中超过缓冲写入.
是的,它可能效率低下.有时,高性能软件仅针对具有更松散的内存排序要求的其他体系结构编写.
是的,原子变量仍然在x86上有用.它们与编译器具有特殊的语义,因此典型的读 - 修改 - 写操作以原子方式发生.如果你有两个线程同时递增一个原子变量(我的意思是std::atomic<T>C++ 11中的一个类型的变量),你可以放心,该值将大2; 没有std::atomic,你可能会得到错误的值,因为一个线程在执行增量时缓存了寄存器中的当前值,即使存储到内存在x86上是原子的.
确实,在 x86 上所有存储都有释放并且所有加载都有获取语义。
这不会也不应该影响您编写 C++ 的方式:要编写并发、无竞争的代码,您必须使用std::atomic构造或锁。
架构细节的意思是,在 x86 上,只要您最多要求获取/释放排序,就会为原子字大小类型的操作生成很少或没有额外的代码。(mfence不过,顺序一致性会发出指令。)但是,您仍然必须使用 C++ 原子类型,并且不能为了获得正确的、格式良好的程序而忽略它们。原子变量的一个重要特性是它们可以防止编译器重新编码,这对程序的正确性至关重要。
(在 C++11 之前,您将不得不使用编译器提供的扩展,例如 GCC 的__sync_*函数套件,这将使编译器正确运行。如果您真的想使用裸变量,您至少必须插入编译器自己的障碍。)
| 归档时间: |
|
| 查看次数: |
1867 次 |
| 最近记录: |