std::memory_order_relaxed 足以检查"Availability"吗?
Is std::memory_order_relaxed enough for checking "Availability"?
我有一个并发对象,它可能或可能每次都持有指向函数的指针。对象的架构如下所示:
struct ConcurrentObject{
//variables
std::atomic<void(*)()> callback;
}
因此,一个线程可能会决定要用这个对象附加回调并将其向前传递:
ConcurrentObject* co = new ConcurrentObject(); //I'm using smart pointers, no worries.
//do some logic
co->callback = someCallback; //void(*)() , this may be difference callback every time
修改后我得到了这个对象,并检查回调是否可用:
auto co = aquireConcurrentObject();
auto callback = co->callback.load();
if (callback){
callback()
}
现在,我们知道,在不指定任何内存顺序的情况下,传递的默认内存顺序是memory_order_seq_cst
它告诉编译器(简而言之)"不要乱写任何读取或写入指令以使程序更快,保持代码指定的指令的相对顺序,并通过 CPU 使其可见"。
我们也知道它是一个很好的性能顽固,因为编译器可以采取的操作受到更多限制。
我的问题是 - std::memory_order_relaxed
足以采取这一行动吗?
是的,你是对的,在你的例子中 std::memory_order_relaxed 是安全的,因为你的代码只依赖于回调是原子的事实。您的代码不受内存操作可能重新排序的影响
回调指针访问的内存顺序会影响回调使用的变量的"可见性"。
如果您的回拨:
1)类似于constexpr,也就是说,除了参数和常量全局变量之外,它不使用任何东西,或者
2) 仅使用变量,这些变量在可能使用回调之前(发生之前)初始化,
然后使用 std::memory_order_relaxed
对于存储和加载都是可以的。
但是如果你的代码在 //do some logic
下初始化了一些变量,由回调使用,那么你至少应该使用 std::memory_order_release
/std::memory_order_acquire
进行相应的存储和加载。否则,执行回调可能会看到这些变量未初始化(更确切地说,它将是来自 C++11 标准的数据竞赛,这是未定义的行为)。
您有办法衡量性能影响吗?更改内存顺序可能看起来像一个良好的性能启动(它似乎有效),但实际上,在大多数应用程序中 - 这并不重要。
在这里更改内存模型意味着任何维护此代码的人都需要格外小心,不要破坏它,因此这是您在执行此类操作时必须承担的另一个风险。
这种优化需要很好地记录下来,并在被证明是性能瓶颈之后进行选择。如果没有必要,请不要惹它。
- valgrind-hellgrind与泄漏检查的结果不同
- C++模板来检查友元函数的存在
- 检查输入是否不是整数或数字
- 试图让变量检查数组中的某些内容
- 检查值是否在集合p1和p2中,但不在p3中
- C++概念:如何使用'concept'检查模板化结构的属性?
- 概念TS检查忽略私有访问修饰符
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- 如何在C++中检查2D数组中负值的输入验证
- C++:正在检查LinkedList中的回文-递归方法-错误
- 使用for循环检查数组中的重复项
- 如何检查一个c++字符串中有多少相同的字符/数字
- 检查不带转换的扫描格式
- 如何检查线程是否锁定
- 清除前检查矢量
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- C++LDAP检查用户是否是特定组的成员
- 检查TCHAR数组输入是否为带符号整数C++
- std::memory_order_relaxed 足以检查"Availability"吗?