问题标签 [relaxed-atomics]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
34 浏览

c++ - 代码和宽松原子的编译器/硬件优化

我一直在听 Herb Sutter 的 Atomic Weapons 演讲,有一张幻灯片,他讨论了已发布的原子变量和代码优化。我的问题更多地与允许编译器优化做什么以及不允许做什么有关。Memory_order_relaxed 就是这种魔法,它允许原子操作在它们所使用的函数内部浮动。

考虑以下代码片段(count 是一个原子变量)(假设 count 的所有用法都已显示)-

具体来说,在线程函数中,count 可以在函数中的任意位置移动。在这种情况下,请澄清我的假设是否正确-

  1. 从逻辑上讲,这意味着 if(...) 也应该随之移动,因此条件可以放在 while(...) 内的任何位置。
  2. 由于 while(...) 包含宽松变量,它应该能够在功能块内不受限制地上下移动。
  3. 可以将 count 变量移出 if(...)/while(...) 并用某种寄存器替换吗?

如果有任何链接可以帮助我更好地理解编译器优化的范围,请添加它们。

0 投票
2 回答
289 浏览

c++ - 比 std::atomic 更便宜的替代品?

我在多线程应用程序中有一类对象,其中每个线程都可以标记要删除的对象,然后中央垃圾收集器线程实际上会删除该对象。线程通过访问内部布尔值的成员方法进行通信:

由于 Thread Sanitizer 一直在抱怨,该 bool 过去已被其他人设为原子。但是,perf 现在表明在内部原子负载期间存在处理开销:

目标平台是 GCC、Aarch64 和 Yocto Linux。

现在我的问题如下:

  • 在这种情况下真的需要原子吗?bool 的转换是一种方式(从 false 到 true),在对象存在时无法返回,因此不一致仅意味着对象稍后被删除,对吗?

  • 是否有替代方案可以std::atomic<bool>使 Thread Sanitizer 静音但在计算上比 Thread Sanitizer 便宜std::atomic<bool>

0 投票
1 回答
115 浏览

c++ - 来自多个线程的 stable_clock::now 的值是否与内存顺序一致?

在一个线程内,steady_clock::now()保证返回单调递增的值。这如何与多个线程观察到的内存排序和读取交互?

这是重要的一点:

这些断言会失败吗?还是我对获取释放内存顺序有误解?

以下主要是对我的代码示例的解释和阐述。

线程t1写入 atomic arg。它还分别记录了写入之前和之后的当前a时间bsteady_clock保证a <= b

线程t2从原子读取arg并保存读取的值ec它还分别记录了读入和读入前后的当前时间dsteady_clock保证c <= d

然后连接两个线程。此时e可能是01

如果e0,则在写入t2之前读取该值。这是否也意味着in之前发生过in t1c = now()t2b = now()t1

如果e1然后在读取t1之前写入值。这是否也意味着in之前发生过in t2a = now()t1d = now()t2


以下是一些无法回答我所问问题的现有问题:

即使使用多核上下文,是否有任何 std::chrono 线程安全保证?

我不是在问是否now()是线程安全的。我知道它是。

跨线程的 stable_clock 是单调的吗?

这个更接近,但该示例使用mutex. 我可以对弱于 的内存排序做出相同的假设seq_cst吗?

0 投票
0 回答
81 浏览

c++ - 为什么 [[carries_dependency]] 不是 C++ 中的默认值?

我知道这memory_order_consume已被弃用,但我试图了解原始设计中的逻辑以及如何[[carries_dependency]]以及kill_dependency应该如何工作。为此,我想要一个特定的代码示例,它会在 IBM PowerPC 或 DEC alpha 或什至具有假设编译器的假设架构上中断,该编译器在 C++11 或 C++14 中完全实现了消费语义。

我能想到的最好的例子是这样的:

我了解此代码中的断言可能会失败。但是,如果您从中删除,断言应该失败吗?如果是这样,为什么会这样?毕竟,您请求了 a ,那么您为什么希望其他访问能够反映获取语义呢?如果删除不会使代码正确,那么(或为所有变量设置默认值)破坏其他正确代码的示例是什么?[[carries_dependency]]fmemory_order_consumev[[carries_dependency]][[carries_dependency]][[carries_dependency]]

我唯一能想到的是,这可能与寄存器溢出有关?如果一个函数将一个寄存器溢出到堆栈上,然后重新加载它,这可能会破坏依赖链。因此,[[carries_dependency]]在某些情况下可能会使事情变得高效(说在调用此函数之前无需在调用者中发出内存屏障),但还要求被调用者在任何寄存器溢出或调用另一个函数之前发出内存屏障,这在其他情况下可能效率较低案例?不过,我在这里抓住了稻草,所以仍然很想听听懂这些东西的人的来信……

0 投票
1 回答
66 浏览

c++ - C ++:将哪个弱原子用于接收异步的缓冲区。RDMA 传输?

Derecho 系统(用于数据复制、分布式协调、Paxos的开源 C++ 库——超快)是围绕异步 RDMA 网络原语构建的。发送方可以使用 RDMA 传输到接收方内存而无需暂停就可以写入接收方。这通常分两步完成:我们在一个操作中传输数据字节,然后通过增加计数器或设置标志来通知接收方:“现在,消息 67 已为您准备好”。很快,接收者将注意到消息 67 已准备就绪,此时它将访问该消息的字节。

预期语义:“看到更新的计数器应该意味着接收者的 C++ 代码将看到消息的字节。” 在 PL 术语中,我们需要在保护更新和消息字节之间设置一个内存栅栏。各个缓存行也必须是顺序一致的:我的守卫将通过诸如 67、68 之类的值,我不想要任何形式的混搭值或非单调排序,例如 C++ 可能出现的情况读取过时的缓存行,或错误地将过时的值保存在内存中。消息缓冲区本身也是如此:这些字节可能会覆盖旧字节,我不想看到某种混搭。

这是我的问题的症结所在:我需要一个弱原子来施加[确切]所需的障碍,而不会引入不必要的开销。哪个注释是合适的?“消息”的弱原子注释是否与计数器(“守卫”)相同?

第二个问题:如果我用适当的弱原子声明我的缓冲区,我是否还需要说它是“易失的”,或者 C++ 会因为内存被声明为弱原子而意识到这一点?

0 投票
1 回答
37 浏览

c++ - std::memory_order_relaxed 与 fetch_add

我正在尝试更深入地了解轻松的内存排序。根据 CPP 参考,没有同步,但是仍然保证原子性。在这种情况下,原子性是否不需要某种形式的同步,例如,fetch_add()下面如何保证只有一个线程将值从yto更新y+1,特别是如果写入可以乱序对不同线程可见?是否存在与相关的隐式同步fetch_add

memory_order_relaxed 松弛操作:对其他读取或写入没有同步或排序约束,仅保证此操作的原子性(请参阅下面的松弛排序)