C++中原子变量的访问速度有多快?

11

我的问题是,使用C++0x的atomic<>类,访问原子变量有多快?缓存层面会发生什么?比如,如果一个线程只是读取它,它需要到RAM中读取吗,还是可以直接从执行它的核心的缓存中读取?假设架构是x86。

我特别想知道的是,如果一个线程只是从中读取,同时没有其他线程在写入,那么惩罚是否与读取普通变量相同。原子变量如何被访问。每次读取是否都隐含着写入,如compare-and-swap? 原子变量是通过使用compare-and-swap来实现的吗?


8
取决于硬件。你有哪些设备在考虑?此外,你实际上没有太多的选择。如果你决定原子操作速度太慢,几乎不能决定不使用它,并且只能希望你没有任何竞争条件! - David Heffernan
数据有多宽?对齐方式是什么? - David Heffernan
2
还有,“if one thread is just reading it”是什么意思?如果只有一个线程在读取,那么您不需要将其设置为原子操作。 - David Heffernan
3
写入线程必须锁定/使指向同一内存的所有其他缓存行无效。完成“写入”后,使用相同缓存行的所有其他处理器必须重新获取缓存行,可以通过从另一个缓存进行嗅探或从内存中获取来实现。获取缓存行后,它将保持有效状态,直到另一个处理器再次使其无效为止。 - Christopher
3
这取决于所使用的内存顺序。如果使用默认的内存顺序(即“顺序一致性”),这可能是正确的,但在更次要的顺序中可能不正确。 - R. Martinho Fernandes
显示剩余6条评论
3个回答

4
如果你想要原始数字,Anger Fog的优化手册中的数据列表应该会有用。此外,英特尔手册有几个章节详细说明多核系统中内存读/写时的延迟,其中应包括由于需要原子写入而导致的总线锁定所引起的减速细节。

我已经阅读过,在新处理器中他们锁定的是缓存而不是整个总线! - MetallicPriest

3
答案并不像你想象的那么简单。它取决于确切的CPU型号,也取决于情况。最糟糕的情况是当你需要在一个变量上执行读-修改-写操作,并且存在冲突(什么是冲突又取决于CPU型号,但最常见的情况是当另一个CPU正在访问相同的缓存行)。
另请参阅.NET或Windows同步原语性能规范

3
原子操作利用特殊的体系结构支持来获得原子性,而不强制所有读/写都要到达主存储器。基本上,每个核心都可以探测其他核心的高速缓存,因此它们通过这种方式了解其他线程操作的结果。
具体性能取决于体系结构。在x86上,许多操作已经是原子的,所以它们是免费的。我见过从10到100个时钟周期的数字,具体取决于体系结构和操作。就比较而言,任何从主存储器中读取的操作需要3000-4000个时钟周期,因此几乎所有平台上的原子操作都比直接访问内存快得多。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接