Ada*_*ark 4 c++ performance multithreading atomic thread-safety
我很好奇在应用程序中使用std::atomic<float>
vs 正常的性能float
。我也很好奇是什么影响了这个。我经常看到有关原子与互斥锁性能的主题,但我发现很难找到有关原子与非原子的信息。
我不是用它来选择使我的代码线程安全与否,只是想了解所涉及的开销。
(编辑:在原始问题的这一点上,我给出了一个示例(见下文),该示例应该说明实现的更改,而不是询问有关该代码的具体问题。这似乎让人们对我问的问题感到困惑我已经拿出来了。)
我基本上想知道影响 std::atomic 性能的广泛因素是什么。是平台吗?它们的使用方式?使用由两个线程访问大致相同数量的原子,而不是一个线程在 95% 的时间内访问它们而另一个线程仅偶尔访问它们是否更慢?
另外,在这方面astd::atomic<int>
和a之间有什么区别std::atomic<float>
吗?
提前致谢,
亚当
来自原始问题的示例:
基本上,我尝试制作一百万个浮点数并向它们写入值 200 次。这对我来说花了 0.87 秒。一旦我将它们更改为std::atomic<float>
,这大约需要 2.5 秒。所以这意味着它的使用成本大约是 3 倍std::atomic<float>
。
我试过这个,但为了读取值而不是写入,发现这是一个正常的float
并且std::atomic<float>
花费相同的时间。
但这是否受到其他因素的影响?如果另一个线程正在写入/读取我的原子,这是否会减慢其他对同一变量的读取/写入速度?大概是这样,但我怎样才能更好地理解这一点?
没有排序参数(即默认值)的原子存储是昂贵的,因为编译器会发出额外的排序指令。On X86
,浮点数的默认(顺序一致)原子存储如下所示:
atomic<float> f;
f.store(3.14);
Run Code Online (Sandbox Code Playgroud)
gcc 产生以下指令:
0x00000000004006d0 <+0>: movl $0x4048f5c3,0x20096a(%rip) # 0x601044 <f>
0x00000000004006da <+10>: mfence
Run Code Online (Sandbox Code Playgroud)
该mence
指令是昂贵的,因为它确保对其他内核的直接可见性(即导致存储缓冲区被刷新)。
您可以尝试在不订购的情况下运行测试:
f.store(3.14, std::memory_order_relaxed);
Run Code Online (Sandbox Code Playgroud)
这将摆脱mfence
并可能显示性能的显着差异。它更接近于非原子商店,如果在某些平台上不相等。
在这方面,a
std::atomic<int>
和 a之间有什么区别std::atomic<float>
吗?
假设两者都是无锁的,可能不是。排序约束是导致性能下降的原因。