std::atomic<int*>::load 应该做一个比较和交换循环吗?
Should std::atomic<int*>::load be doing a compare-and-swap loop?
摘要:我曾希望,具有std::memory_order_relaxed
的std::atomic<int*>::load
至少在加载值很少更改时直接直接加载指针的性能。我认为原子负载的性能要比Visual Studio C 2012上的正常负载要差得多,因此我决定调查。事实证明,原子负载是作为比较和swap循环实现的,我怀疑这不是最快的实现。
问题:是否有某种原因std::atomic<int*>::load
需要进行比较和swap循环?
背景:我相信MSVC 2012正在对基于此测试程序的指针的原子负载进行比较和换循环:
#include <atomic>
#include <iostream>
template<class T>
__declspec(noinline) T loadRelaxed(const std::atomic<T>& t) {
return t.load(std::memory_order_relaxed);
}
int main() {
int i = 42;
char c = 42;
std::atomic<int*> ptr(&i);
std::atomic<int> integer;
std::atomic<char> character;
std::cout
<< *loadRelaxed(ptr) << ' '
<< loadRelaxed(integer) << ' '
<< loadRelaxed(character) << std::endl;
return 0;
}
我正在使用__declspec(noinline)
功能,以隔离与原子负载相关的汇编指令。我制作了一个新的MSVC 2012项目,添加了一个X64平台,选择了发行配置,在调试器中运行了程序,并查看了拆卸。事实证明,std::atomic<char>
和std::atomic<int>
参数最终都会给loadRelaxed<int>
提供相同的调用 - 这一定是优化器所做的。这是被调用的两个载荷实例的拆卸:
loadRelaxed<int * __ptr64>
000000013F4B1790 prefetchw [rcx]
000000013F4B1793 mov rax,qword ptr [rcx]
000000013F4B1796 mov rdx,rax
000000013F4B1799 lock cmpxchg qword ptr [rcx],rdx
000000013F4B179E jne loadRelaxed<int * __ptr64>+6h (013F4B1796h)
loadRelaxed<int>
000000013F3F1940 prefetchw [rcx]
000000013F3F1943 mov eax,dword ptr [rcx]
000000013F3F1945 mov edx,eax
000000013F3F1947 lock cmpxchg dword ptr [rcx],edx
000000013F3F194B jne loadRelaxed<int>+5h (013F3F1945h)
指令 lock cmpxchg
是原子比较和swap,我们在这里看到原子上加载 char
, int
或 int*
的代码是一个比较和swap循环。我还为32位x86构建了此代码,该实现仍然基于lock cmpxchg
。
问题:是否有某些原因std::atomic<int*>::load
需要进行比较和swap循环?
我不相信放松的原子载荷需要比较和交换。最后,这个std ::原子实现并不能用于我的目的,但是我仍然想拥有界面,因此我使用MSVC的屏障interinss制作了自己的std :: Atomic。对于我的用例,这比默认的std::atomic
具有更好的性能。您可以在此处查看代码。对于所有负载和存储的订单,应该将其实现到C 11规格。BTW GCC 4.6在这方面不是更好。我不知道GCC 4.7。
- 如何在 c++ 中比较 2 个链表并将匹配的数据放入另一个链表中
- C++设置了一个用于排序的比较器和另一个用于唯一性的比较器
- 绘制一个对象,比较模具缓冲区的两个不同值
- 我如何将一个变量与另一个变量进行比较,例如我想如果(var1 > var2 x 1),然后执行此 c++
- 如何比较文件中包含的下一个字符
- 为 RocksDB 实现一个比较器
- 将当前多边形数据单元与下一个多边形单元格 - VTK 进行比较
- 比较最后一个字符,不区分大小写(带谓词?
- 如何键入定义一个专门的 std::set 模板,使用特定的比较函数实例化
- 与C++中不止一个字符进行比较
- 将 32 位浮点数和不强制转换的 32 位整数与双精度进行比较,当其中一个值可能太大而无法完全适合另一种类型时
- 在数组中仅比较一个字符
- 如何将一个值与整个数组进行比较
- 如何制作一个从文件中读取密码并与用户编写的密码进行比较的 c++ 程序
- C++:将当前时间与下一个工作时间进行比较
- 我怎样才能洗牌给定大小的数组并将其与C++中另一个相同大小的数组进行比较
- 比较一个链接列表与另一个黑名单与词频列表C++
- 为什么在汇编代码中比较一个在范围内的数字时会发生分支
- 是否有一种方法可以正确地比较一个float值是否大于/小于另一个
- 比较一个向量中向量的大小,得到最大的