相关疑难解决方法(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
查看次数

标准C++ 11是否保证memory_order_seq_cst阻止StoreLoad在原子周围重新排序非原子?

标准C++ 11是否保证memory_order_seq_cst阻止StoreLoad重新排序原子操作以进行非原子内存访问?

众所周知,std::memory_orderC++ 11中有6 个,它指定了如何围绕原子操作对常规的非原子内存访问进行排序 - 工作草案,编程语言C++标准2016-07-12:http:/ /www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf

§29.3顺序和一致性

§29.3/ 1

枚举memory_order指定1.10中定义的详细常规(非原子)内存同步顺序,并且可以提供操作排序.其枚举值及其含义如下:

众所周知,这6个memory_orders会阻止其中一些重新排序:

在此输入图像描述

但是,是否会memory_order_seq_cst阻止StoreLoad围绕原子操作重新排序以进行常规的非原子内存访问,或仅针对其他具有相同原子的原子进行重新排序memory_order_seq_cst

即,如果我们同时使用std::memory_order_seq_cstSTORE和LOAD,或仅用于其中一个,则阻止此StoreLoad重新排序?

std::atomic<int> a, b;
b.store(1, std::memory_order_seq_cst); // Sequential Consistency
a.load(std::memory_order_seq_cst); // Sequential Consistency
Run Code Online (Sandbox Code Playgroud)

关于Acquire-Release语义是明确的,它完全指定了跨原子操作的非原子内存访问重新排序:http://en.cppreference.com/w/cpp/atomic/memory_order


为防止StoreLoad重新排序,我们应该使用std::memory_order_seq_cst.

两个例子:

  1. std::memory_order_seq_cst对于STORE和LOAD:MFENCE

StoreLoad无法重新排序 - GCC 6.1.0 x86_64:https://godbolt.org/g/mVZJs0

std::atomic<int> a, b;
b.store(1, std::memory_order_seq_cst); // can't be executed after LOAD
a.load(std::memory_order_seq_cst); // …
Run Code Online (Sandbox Code Playgroud)

c++ concurrency standards multithreading c++11

13
推荐指数
1
解决办法
870
查看次数

x86可以重新排序一个具有更宽负载的窄存储吗?

英特尔®64和IA-32架构软件开发人员手册说:

8.2.3.4负载可以通过早期存储
重新排序到不同位置 Intel-64内存排序模型允许将负载与早期存储重新排序到不同位置.但是,加载不会与商店重新排序到同一位置.

那些与之前的商店部分或完全重叠但是没有相同起始地址的负载呢?(有关具体案例,请参阅本文末尾)


假设以下类似C的代码:

// lock - pointer to an aligned int64 variable
// threadNum - integer in the range 0..7
// volatiles here just to show direct r/w of the memory as it was suggested in the comments
int TryLock(volatile INT64* lock, INT64 threadNum)
{
    if (0 != *lock)
        return 0;                           // another thread already had the lock

    ((volatile INT8*)lock)[threadNum] = 1;  // take the lock by setting our byte

    if (1LL << 8*threadNum != …
Run Code Online (Sandbox Code Playgroud)

x86 assembly multithreading locking x86-64

10
推荐指数
2
解决办法
694
查看次数

标签 统计

c++ ×2

c++11 ×2

concurrency ×2

multithreading ×2

assembly ×1

atomic ×1

locking ×1

standards ×1

x86 ×1

x86-64 ×1