相关疑难解决方法(0)

什么时候使用volatile多线程?

如果有两个线程访问全局变量,那么许多教程都说使变量volatile变为阻止编译器将变量缓存在寄存器中,从而无法正确更新.但是,访问共享变量的两个线程是通过互斥锁来调用保护的东西不是吗?但是在这种情况下,在线程锁定和释放互斥锁之间,代码处于一个关键部分,只有那个线程可以访问变量,在这种情况下变量不需要是volatile?

那么多线程程序中volatile的用途/目的是什么?

c++ concurrency multithreading atomic volatile

121
推荐指数
3
解决办法
5万
查看次数

INC指令与ADD 1:重要吗?

来自Ira Baxter回答,为什么INC和DEC指令不会影响进位标志(CF)?

大多数情况下,我远离INCDEC现在,因为他们做的部分条件代码更新,这样就可以在管道中引起滑稽的摊位,和ADD/ SUB没有.因此,无关紧要(大多数地方),我使用ADD/ SUB避免失速.我使用INC/ DEC仅在保持代码较小的情况下,例如,适合高速缓存行,其中一个或两个指令的大小产生足够的差异.这可能是毫无意义的纳米[字面意思!] - 优化,但我在编码习惯上相当老派.

我想问一下为什么它会导致管道中的停顿,而添加不会?毕竟,无论是ADDINC更新标志寄存器.唯一的区别是INC不更新CF.但为什么重要呢?

performance x86 assembly increment micro-optimization

26
推荐指数
2
解决办法
4234
查看次数

哪个是x86上更好的写屏障:lock + addl还是xchgl?

Linux内核lock; addl $0,0(%%esp)用作写屏障,而RE2库xchgl (%0),%0用作写屏障.有什么区别,哪个更好?

x86还需要读屏障指令吗?RE2将其读屏障功能定义为x86上的无操作,而Linux lfence根据SSE2是否可用将其定义为无操作或无操作.什么时候lfence需要?

x86 assembly memory-barriers

23
推荐指数
4
解决办法
7771
查看次数

标准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
查看次数

lock xchg与mfence具有相同的行为吗?

我想知道的是lock xchg,mfence从一个线程访问内存位置的角度来看是否会有类似的行为,这个内存位置正在被其他线程进行变异(让我们随便说).它能保证我获得最新的价值吗?之后的内存读/写指令?

我混淆的原因是:

8.2.2"读取或写入不能通过I/O指令,锁定指令或序列化指令重新排序."

-Intel 64 Developers Manual Vol.3

这是否适用于线程?

mfence 状态:

对MFENCE指令之前发出的所有内存加载和存储到内存指令执行序列化操作.此序列化操作保证在MFENCE指令之前的任何加载或存储指令全局可见之前,在程序顺序之前的每条加载和存储指令都是全局可见的.MFENCE指令针对所有加载和存储指令,其他MFENCE指令,任何SFENCE和LFENCE指令以及任何序列化指令(例如CPUID指令)进行排序.

-Intel 64 Developers Manual Vol 3A

听起来更有力.因为它听起来mfence几乎正在刷写写缓冲区,或者至少延伸到写缓冲区和其他内核以确保我未来的加载/存储是最新的.

当基准标记时,两个指令都需要约100个循环才能完成.所以我无论如何都看不出那么大的差异.

主要是我只是困惑.我的指令基于lock互斥体使用,但后来这些包含没有内存栅栏.然后,我看到锁免费使用内存栅栏编程,但没有锁.我知道AMD64有一个非常强大的内存模型,但过时的值可以在缓存中持续存在.如果lock行为与行为不同,mfence那么互斥量如何帮助您查看最新值?

x86 assembly multithreading cpu-architecture memory-barriers

10
推荐指数
1
解决办法
1145
查看次数

atomic_thread_fence(memory_order_seq_cst)是否具有完整内存屏障的语义?

完整/通用内存屏障是在屏障之前指定的所有LOAD和STORE操作看起来发生在屏障之后相对于系统的其他组件指定的所有LOAD和STORE操作之前的屏障.

根据cppreference,memory_order_seq_cst等于memory_order_acq_rel在所有标记的操作上加上单个总修改顺序.但据我所知,C++ 11中的获取和释放栏都没有强制执行#StoreLoad(加载后存储)排序.发布围栏要求以后的任何写入都不能重新排序先前的读/写; 获取围栏要求不能对任何先前的读取重新排序后续读/写.如果我错了,请纠正我;)

举个例子,

atomic<int> x;
atomic<int> y;

y.store(1, memory_order_relaxed);            //(1)
atomic_thread_fence(memory_order_seq_cst);   //(2)
x.load(memory_order_relaxed);                //(3)
Run Code Online (Sandbox Code Playgroud)

是否允许优化编译器将指令(3)重新排序到之前(1),以使其有效看起来像:

x.load(memory_order_relaxed);                //(3)
y.store(1, memory_order_relaxed);            //(1)
atomic_thread_fence(memory_order_seq_cst);   //(2)
Run Code Online (Sandbox Code Playgroud)

如果这是一个有效的转换,那么它证明atomic_thread_fence(memory_order_seq_cst)并不一定包含完整障碍所具有的语义.

c++ c++11

7
推荐指数
2
解决办法
1256
查看次数

C++中的内存模型:顺序一致性和原子性

我在C++ 11中有一些与内存模型有关的问题.

在29.幻灯片上的https://www.think-cell.com/en/career/talks/pdf/think-cell_talk_memorymodel.pdf上写

C++内存模型可确保顺序一致性

但是,在我以前的帖子中,我了解到C++内存具有弱内存模型 - 编译器可以根据需要进行重新排序 - 他必须满足规则那样满足.

c++ x86 multithreading c++11

6
推荐指数
2
解决办法
1536
查看次数

加载和存储是否只有重新排序的指令?

我已经阅读了很多关于内存排序的文章,并且所有这些文章都只说CPU重新加载和存储.

CPU(我对x86 CPU特别感兴趣)是否仅重新排序加载和存储,并且不重新排序它具有的其余指令?

x86 cpu-architecture memory-barriers

6
推荐指数
2
解决办法
915
查看次数

为什么 LOCK 是 x86 上的完整屏障?

为什么LOCK前缀会导致 x86 上的完全障碍?(因此它耗尽了存储缓冲区并具有顺序一致性)

对于LOCK/read-modify-write 操作,不需要完全屏障,对缓存行的独占访问似乎就足够了。这是设计选择还是有其他限制?

x86 cpu-architecture memory-barriers

6
推荐指数
1
解决办法
380
查看次数

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

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

-- 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
查看次数