关于c ++:std :: atomic和non-atomic变量的性能如何?

What is the performance of std::atomic vs non-atomic variables?

我对在应用程序中使用std::atomic与常规float的性能感到好奇。我也对影响这一点感到好奇。我经常看到有关原子与互斥的性能的主题,但是我发现很难找到有关原子与非原子的信息。

我不是想以此作为选择使我的代码具有线程安全性或非线程安全性的方法,只是想了解所涉及的开销。

(编辑:在原始问题的这一点上,我给出了一个示例(请参见下文),该示例应被用来说明实现的更改,而不是询问有关该代码的特定问题。这似乎使人们对我的要求感到困惑。我拿出来了。)

我基本上想知道影响std :: atomic性能的主要因素是什么。是平台吗?它们的使用方式?使用两个线程访问的原子量大致相等,而不是使用一个线程95%的时间访问它们而另一个线程只是偶尔访问一个原子,会更慢吗?

此外,在这方面std::atomicstd::atomic之间是否有区别?

提前致谢,

亚当

来自原始问题的示例:

基本上,我尝试制作一百万个浮点数并将其值写入200次。我花了0.87秒。一旦将它们更改为std::atomic,这大约需要2.5秒。因此,这意味着使用std::atomic的成本大约是其3倍。

我尝试了此操作,但是读取的是值而不是写入的值,结果发现正常的floatstd::atomic花费的时间相同。

但这会受到其他因素的影响吗?如果另一个线程正在写/读我的原子,这是否会减慢其他对同一变量的读/写速度?大概是这样,但是我该如何更好地理解呢?


没有排序参数(即默认值)的原子存储很昂贵,因为编译器会发出其他排序指令。
X86上,默认(顺序一致)的float原子存储如下所示:

1
2
atomic<float> f;
f.store(3.14);

gcc产生以下指令:

1
2
0x00000000004006d0 <+0>:     movl   $0x4048f5c3,0x20096a(%rip)        # 0x601044 <f>
0x00000000004006da <+10>:    mfence

mence指令非常昂贵,因为它可以确保直接看到其他内核(即导致刷新存储缓冲区的原因)。

您可以尝试运行测试而无需订购:

1
f.store(3.14, std::memory_order_relaxed);

这将摆脱mfence并可能显示出明显的性能差异。 如果在某些平台上不相等,那么它与非原子商店的距离更近。

is there any difference between a std::atomic and a std::atomic in this regard?

假设两者都是无锁的,可能不是。 排序约束是导致性能降低的原因。