相关疑难解决方法(0)

获取/发布与顺序一致的内存顺序

对于std::atomic<T>T是基本类型的任何地方:

如果我使用std::memory_order_acq_relfetch_xxx操作,以及std::memory_order_acquire用于load操作和std::memory_order_releasestore操作盲目(我的意思是,就像重置这些功能的默认内存排序)

  • 结果是否与我使用std::memory_order_seq_cst(用作默认值)的任何声明操作相同?
  • 如果结果相同,那么这种用法std::memory_order_seq_cst在效率方面是否与使用不同?

c++ concurrency atomic c++11

36
推荐指数
2
解决办法
8122
查看次数

memory_order_seq_cst和memory_order_acq_rel有何不同?

存储是释放操作,负载是两者的获取操作.我知道这memory_order_seq_cst意味着要为所有操作强加一个额外的总排序,但是我没有建立一个例子,如果所有的操作memory_order_seq_cst都被替换,那就不是这样了memory_order_acq_rel.

我是否会遗漏某些内容,或者差异仅仅是文档效果,即memory_order_seq_cst如果有人打算不使用更轻松的模型并且memory_order_acq_rel在约束轻松模型时使用,则应该使用?

c++ memory-model c++11 stdatomic

30
推荐指数
3
解决办法
6657
查看次数

ARM STLR 内存排序语义

我正在努力了解 ARM STLR 的确切语义。

根据文档,它具有发布语义。所以如果你有 STLR 商店,你会得到:

[StoreStore][LoadStore]
X=r1
Run Code Online (Sandbox Code Playgroud)

其中X是内存和r1一些寄存器。

问题是释放存储和获取加载无法提供顺序一致性:

[StoreStore][LoadStore]
X=r1
r2=Y
[LoadLoad][LoadStore]
Run Code Online (Sandbox Code Playgroud)

在上述情况下,允许重新排序 X=r1 和 r2=Y。为了使这个顺序一致,需要添加一个[StoreLoad]:

[StoreStore][LoadStore]
X=r1
[StoreLoad]
r2=Y
[LoadLoad][LoadStore]
Run Code Online (Sandbox Code Playgroud)

你通常在商店里这样做,因为装载更频繁。

在 X86 上,普通存储是发布存储,普通加载是获取加载。[StoreLoad] 可以通过 MFENCE 来实现,或者使用LOCK ADDL %(RSP),0Hotspot JVM 中的方式来实现。

当查看ARM文档时,LDAR似乎具有获取语义;所以这将是[LoadLoad][LoadStore]。

但 STLR 的语义很模糊。当我使用 memory_order_seq_cst 编译 C++ 原子时,只有一个 STLR;没有DMB。所以看来STLR比release store有更强的内存排序保证。对我来说,在栅栏层面上,STLR 相当于:

 [StoreStore][LoadStore]
 X=r1
 [StoreLoad]
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下吗?

concurrency multithreading arm atomic arm64

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

是否会在其他线程中始终以相同顺序看到对不同线程中不同位置的两次原子写操作?

与我之前的问题类似,请考虑以下代码

-- Initially --
std::atomic<int> x{0};
std::atomic<int> y{0};

-- Thread 1 --
x.store(1, std::memory_order_release);

-- Thread 2 --
y.store(2, std::memory_order_release);

-- Thread 3 --
int r1 = x.load(std::memory_order_acquire);   // x first
int r2 = y.load(std::memory_order_acquire);

-- Thread 4 --
int r3 = y.load(std::memory_order_acquire);   // y first
int r4 = x.load(std::memory_order_acquire);
Run Code Online (Sandbox Code Playgroud)

怪异的结果 r1==1, r2==0,并r3==2, r4==0有可能在C ++ 11内存模型下,这种情况下?如果我要全部替换std::memory_order_acq_rel成该std::memory_order_relaxed怎么办?

在x86上,这样的结果似乎是被禁止的,请参见此SO问题,但我一般是在询问C ++ 11内存模型。

奖励问题:

我们都同意,与std::memory_order_seq_cst怪异的结果不会在C ++ 11被允许。现在,赫伯·萨特(Herb Sutter)在他著名的- …

c++ concurrency memory-model c++11 stdatomic

4
推荐指数
3
解决办法
540
查看次数

全局不可见的加载说明

由于存储负载转发,某些负载指令能否在全局范围内不可见?换句话说,如果加载指令从存储缓冲区中获取其值,则它永远不必从高速缓存中读取。
通常说来,当从L1D缓存读取负载时,该负载在全局范围内可见,因此,未从L1D读取的负载应使其在全局上不可见。

cpu-architecture memory-barriers cpu-cache

3
推荐指数
1
解决办法
297
查看次数

使用 memory_order_seq_cst 和 memory_order_release 可能的排序

参考下面的代码

auto x = std::atomic<std::uint64_t>{0};
auto y = std::atomic<std::uint64_t>{0};

// thread 1
x.store(1, std::memory_order_release);
auto one = y.load(std::memory_order_seq_cst);

// thread 2
y.fetch_add(1, std::memory_order_seq_cst);
auto two = x.load(std::memory_order_seq_cst);
Run Code Online (Sandbox Code Playgroud)

这里有可能onetwo都为 0 吗?


(我似乎遇到了一个错误,在上面的代码运行后,如果onetwo都可以保持 0 的值,则可以解释该错误。并且排序规则太复杂,我无法弄清楚上面可以进行哪些排序。)

c++ multithreading memory-barriers stdatomic c++20

2
推荐指数
1
解决办法
719
查看次数