相关疑难解决方法(0)

num ++是'int num'的原子吗?

一般地,对于int num,num++(或++num),作为读-修改-写操作中,是不是原子.但我经常看到编译器,例如GCC,为它生成以下代码(在这里尝试):

在此输入图像描述

由于第5行对应于num++一条指令,我们可以得出结论,在这种情况下num++ 是原子的吗?

如果是这样,是否意味着如此生成num++可以在并发(多线程)场景中使用而没有任何数据争用的危险(例如,我们不需要制作它,std::atomic<int>并强加相关成本,因为它是无论如何原子)?

UPDATE

请注意,这个问题不是增量是否原子的(它不是,而且是问题的开头行).它是否可以在特定场景中,即在某些情况下是否可以利用单指令性质来避免lock前缀的开销.而且,作为公认的答案约单处理器的机器,还有部分提到这个答案,在其评论和其他人谈话解释,它可以(尽管不是C或C++).

c c++ assembly multithreading atomic

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

为什么在x86上对自然对齐的变量进行整数赋值?

我一直在读这篇关于原子操作的文章,它提到了32位整数赋值在x86上是原子的,只要该变量是自然对齐的.

为什么自然对齐确保原子性?

c c++ concurrency x86 atomic

28
推荐指数
2
解决办法
5386
查看次数

Linux:为什么sig_atomic_t typedef'ed为int?

在我的Linux机器上,sig_atomic_t是一个普通的老int.是否ints具有特殊的原子质量?

$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
...
Thread model: posix
gcc version 4.3.2 (Debian 4.3.2-1.1) 

$ echo '#include <signal.h>' | gcc -E - | grep atomic
typedef int __sig_atomic_t;
typedef __sig_atomic_t sig_atomic_t;
Run Code Online (Sandbox Code Playgroud)

c linux signals

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

x86上的原子性

8.1.2总线锁定

Intel 64和IA-32处理器提供LOCK#信号,该信号在某些关键存储器操作期间自动置位,以锁定系统总线或等效链路.当该输出信号被断言时,来自其他处理器或总线代理的用于控制总线的请求被阻止.软件可以指定在遵循LOCK语义的其他情况下将LOCK前缀添加到指令之前.

它来自英特尔手册,第3卷

听起来内存上的原子操作将直接在内存(RAM)上执行.我很困惑,因为当我分析装配输出时,我看到"没什么特别的".基本上,生成的汇编输出std::atomic<int> X; X.load()只会产生"额外"的影响.但是,它负责正确的内存排序,而不是原子性.如果我理解得X.store(2)恰到好处mov [somewhere], $2.就这样.它似乎没有"跳过"缓存.我知道将对齐(例如int)移动到内存是原子的.但是,我很困惑.


所以,我提出了疑问,但主要问题是:

CPU如何在内部实现原子操作?

c++ x86 multithreading atomic memory-barriers

18
推荐指数
1
解决办法
5684
查看次数

是x86 CMPXCHG原子,如果是这样,为什么需要LOCK?

Intel的文档

该指令可以与LOCK前缀一起使用,以允许指令以原子方式执行.

我的问题是

  1. 可以CMPXCHG用内存地址操作吗?从文档看来似乎没有,但任何人都可以确认只能在寄存器中使用实际的VALUE,而不是内存地址吗?

  2. 如果CMPXCHG不是原子级和高级语言级CAS必须通过LOCK CMPXCHG(带LOCK前缀)来实现,那么引入这样一条指令的目的是什么?

concurrency x86 compare-and-swap

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

在执行过程中中断指令

假设CPU正在运行汇编指令,例如,FOO将在几个时钟(例如10)中执行

中断请求刚好在执行过程中FOO,处理器需要中断.它是否等待命令正确执行,或FOO中止并将重新启动?考虑到不同类型的中断优先级,它的行为是否有所不同?

x86 assembly interrupt

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

在内存位置调用 `add` 是否比在寄存器上调用它然后移动值更快?

什么更快:

add DWORD PTR [rbp-0x4],1
Run Code Online (Sandbox Code Playgroud)

或者

 mov    eax,DWORD PTR [rbp-0x4]
 add    eax,1
 mov    DWORD PTR [rbp-0x4],eax
Run Code Online (Sandbox Code Playgroud)

我已经看到编译器生成的第二个代码,所以也许调用add寄存器要快得多?

x86 assembly x86-64 micro-optimization

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