C++11 std::atomic_fetch_add vs __sync_fetch_and_add
C++11 std::atomic_fetch_add vs __sync_fetch_and_add
我目前无法正确理解新std::atomic
类型的用法。对于我的情况,我有以下假设:
- 我在内存中存储了
uint64_t
值的连续内存位置 - 我有两种访问方式—简单增量和原子增量
最初我实现了类似的方法
uint64_t inc(const size_t pos) { return _data[pos]++; }
uint64_t atomic_inc(const size_t pos) { return __sync_fetch_and_add(&_data[pos], 1); }
现在我想把它正确地移植到C++11,并想知道我应该如何正确地处理它。根据我对std::atomic_fetch_add的理解,基本上需要一个原子积分值来实现这一点。然而,我需要如何正确地实现这一点,以便使用原子变量指向某个位置并增加值?
谢谢!
您不能使用C++11工具来获得对未声明为原子类型的变量的原子访问。您需要将uint64_t
的数组替换为std::atomic<uint64_t>
的数组。在许多平台上,这将具有与普通uint64_t
相同的大小和对齐方式,但所有操作都是原子操作。
然后可以使用data[pos].fetch_add(1,memory_order)
对指定的memory_order
执行原子增量。如果您需要std::memory_order_seq_cst
的内存顺序(这可能是最接近GCC __sync_fetch_and_add
的),那么可以省略内存顺序,或者您可以使用增量运算符,例如data[pos]++
。
你不能。
一个C++11原子对象封装了它的基类型。它不提供对其值的lvalue访问,也不能将其设置为对基础类型的预先存在的对象(在给定的内存位置)提供原子操作。
根据平台的不同,任何给定的原子类型都可能有特殊要求(例如更强的对齐约束)或需要辅助数据(大多数原子类型不能保证是无锁定的)
做您想做的事情仍然需要特定于平台的功能。
如果你想做非原子增量,你能得到的最接近的是:
atomic<uint64_t> data(initial_value);
data.store(data.load(memory_order_relaxed) + 1, memory_order_relaxed);
这仍然会执行原子加载和存储,但不会执行内存围栏或原子读修改写操作。
相关文章:
- Visual Studio - Cmake Project - Add NetCDF
- 在 atomic() 中 ++、add operation 和 fetch_add() 有什么区别
- wxImageList::Add()始终返回0
- 函数 C::add() 中不允许将'C *'隐式转换为'A *'
- C++有"not equal compare and exchange"或"fetch add on not equal"吗?
- 如何在qt中修复"No query Unable to fetch row"
- gRPC trace.cc 的方法 TraceFlagList::Add(TraceFlag* flag) 使其链接列表
- 如何将用户定义的格式标志"add" basic_ostream?
- 'Cannot add two pointers'添加带有 WCHAR 的 LPCWSTR
- Qt应用程序中的"No query Unable to fetch row"
- Fetch API 使用 Electron 使用非 HTTP-Scheme,但不使用 CEF
- 在创建完整对象之前编写 if-can-add check 方法的正确方法?
- 使用 Git init、fetch 和 checkout 克隆 Git 存储库
- CMake add library libpq (postgreSQL) mac c++ clion
- 收到错误:C3867 '<int>Template_class::add':非标准语法;将指针指向带有模板的函数时
- 呼叫'php :: Extension :: add()没有匹配函数
- 使用intel内联汇编程序对bigint-add进行进位编码
- C++ 中头文件中的 Add 方法出错
- 二进制'+=':未找到采用类型 'Add' C++ 的全局运算符
- 对atomic fetch和add的硬件支持vs fetch和or