相关疑难解决方法(0)

STLR(B) 是否在 ARM64 上提供顺序一致性?

对于在原子数据类型(例如std::atomic<uint8_t>)的对象上执行的存储,GCC 生成:

  • MOV释放存储( )情况下的指令std::memory_order_release
  • XCHG顺序一致存储情况下的指令( std::memory_order_seq_cst)。

当目标架构为 x86_64 时。然而,当是ARM64(AArch64)时,在这两种情况下,GCC都会生成相同的指令,即STLRB. 没有生成其他指令(例如内存屏障),Clang 也会发生同样的情况。这是否意味着这条被描述为具有存储-释放语义的指令实际上也提供了顺序一致性?

例如,如果在两个内核上运行的两个线程将执行STLRB不同内存位置的存储,那么这两个存储的顺序是否唯一?这样所有其他线程都保证遵守相同的顺序吗?

我之所以问,是因为根据这个答案,使用acquire-loads ,不同的线程可能会观察到不同的release-store顺序。为了观察相同的顺序,需要顺序一致性。

现场演示: https: //godbolt.org/z/hajMKnd53

c++ x86-64 atomic memory-model arm64

8
推荐指数
1
解决办法
775
查看次数

获取发布内存顺序与顺序一致性不同的实际示例是什么?

显然,顺序一致的原子操作的有效可观察行为与有效C++程序中的仅获取释放操作不同.定义在C++标准(自C++ 11以来)或此处给出.

但是,我从来没有遇到过一个算法或数据结构的真实例子,其中获取 - 释放语义不足并且需要顺序一致性.

什么是真实世界算法或数据结构的实际例子,其中需要顺序一致性并且获取 - 释放内存顺序是不够的?

注意,即使std::mutex不保证顺序一致性.

c++ multithreading atomic memory-model c++11

7
推荐指数
1
解决办法
695
查看次数

Aarch64 上 C++11 原子的部分重新排序

我正在查看来自 gcc 的 rmw 原子编译器输出,并注意到一些奇怪的东西 - 在 Aarch64 上,诸如 fetch_add 之类的 rmw 操作可以在宽松的负载下部分重新排序。

在 Aarch64 上,可能会为以下代码生成 value.fetch_add(1, seq_cst)

.L1:
    ldaxr x1, [x0]
    add x1, x1, 1
    stlxr w2, x1, [x0]
    cbnz L1
Run Code Online (Sandbox Code Playgroud)

但是,在 ldaxr 之前发生的加载和存储可能会被重新排序,超过 stlxr 之后发生的加载和加载/存储(请参阅此处)。GCC 不会添加围栏来防止这种情况发生 - 这里有一小段代码演示了这一点:

void partial_reorder(std::atomic<uint64_t> loader, std::atomic<uint64_t> adder) {
    loader.load(std::memory_order_relaxed); // can be reordered past the ldaxr
    adder.fetch_add(1, std::memory_order_seq_cst);
    loader.load(std::memory_order_relaxed); // can be reordered past the stlxr
}
Run Code Online (Sandbox Code Playgroud)

生成

partial_reorder(std::atomic<int>, std::atomic<int>):
    ldr     w2, [x0] @ reordered down …
Run Code Online (Sandbox Code Playgroud)

c++ concurrency multithreading atomic c++11

4
推荐指数
1
解决办法
404
查看次数

标签 统计

atomic ×3

c++ ×3

c++11 ×2

memory-model ×2

multithreading ×2

arm64 ×1

concurrency ×1

x86-64 ×1