CPU中的原子操作

原创 2018年04月16日 20:40:52

今天在学习多线程时突然想到一个问题,CPU的CAS操作保证了原子性,但是现在的CPU都是多核心可以并行运算的多核CPU了,那CPU怎么实现并行运算时而又能保证对内存操作的原子性呢?

于是查阅了一些资料,有了以下了解:

所谓原子操作,就是”不可中断的一个或一系列操作”

1.单核CPU的原子操作

在单核CPU中, 能够在一个指令中完成的操作都可以看作为原子操作, 因为中断只发生在指令间.

也就是说单核CPU由于不存在多核心并行运算的情况,所有的操作其实都可以视为是原子的,就相当于我们如果只有一只手,就不能一边打字一边抠脚了,所以打字和抠脚的行为,变成了串行的行动,不能并行进行,所以都是原子性操作。

2.多核CPU的原子操作

典型的例子就是decl指令(递减指令), 它细分为三个过程: “读->改->写”, 涉及两次内存操作. 如果多个CPU运行的多个进程在同时对同一块内存执行这个指令, 那情况是无法预测的.

可以看到多核CPU的情况下,就会出现类似我们多线程中出现的问题,对于同一块内存中的变量,多个核心同时读写修改数据的话,就会出现不可预期的错误。

那么CPU是怎么解决这个问题的呢?其实和我们软件平台实现思路很像,就是使用锁机制(回想一下JAVA中的同步锁)

软件级别的原子操作是依赖于硬件支持的. 在x86体系中, CPU提供了HLOCK pin引线, 允许CPU在执行某一个指令(仅仅是一个指令)时拉低HLOCK pin引线的电位, 直到这个指令执行完毕才放开. 从而锁住了总线, 如此在同一总线的CPU就暂时无法通过总线访问内存了, 这样就保证了多核处理器的原子性. (想想这机制对性能影响挺大的).

通俗来讲就是你在被警察抓住了以后,一只手被手铐锁住,就只有另一只手能做事了,也就是说在执行原子操作时,CPU保证只有一个核心能对内存进行操作,这样以来就不会出现多个核心同时运算并回写内存的情况了

3.哪些操作可以确定为原子操作了?

对于非long和double基本数据类型的”简单操作”都可以看作是原子的. 例如: 赋值和返回. 大多数体系中long和double都占据8个字节, 操作系统或者JVM很可能会将写入和读取操作分离为两个单独的32位的操作来执行, 这就产生了在一个读取和写入过程中一个上下文切换(context switch), 从而导致了不同任务线程看到不正确结果的的可能性.

递增, 递减不是原子操作: i++反汇编的汇编指令: (需要三条指令操作, 和两个内存访问, 一次寄存器修改)

// x86指令体系
movl i, %eax                            //内存访问, 读取i变量的值到cpu的eax寄存器
addl $1, %eax                         //增加寄存器中的值
movl %eax, i                            //写入寄存器中的值到内存

问:如何实现x++的原子性?

在单处理器上,如果执行x++时,禁止多线程调度,就可以实现原子。因为单处理的多线程并发是伪并发。
在多处理器上,需要借助cpu提供的Lock功能。锁总线。读取内存值,修改,写回内存三步期间禁止别的CPU访问总线。同时我估计使用Lock指令锁总线的时候,OS也不会把当前线程调度走了。要是调走了,那就麻烦了。

最后,我的一些理解和想法:

  1. 对于CAS操作,编译器会自动汇编成CPU可以实现原子操作的汇编代码(不同CPU下实现可能不同,但是一定会借助某些锁实现汇编代码块的原子性)。
  2. 使用CAS实现无锁同步的优点:减少操作系统阻塞线程的负担,直接使用硬件级别的锁必然要比在其之上的系统调用(比如OS实现的mutex互斥锁)更节省资源。

参考资料:

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CringKong/article/details/79966161

并发,cpu,时间片轮转,原子操作

突然想到一个问题,并发就是cpu时间片轮转,如A,B两个任务两个并发使用一个cpu,那么A和B是怎么轮转的呢?执行到A的哪里,就去执行B,然后再回来执行A? 即cpu处理到什么时候,就将A挂起,然后...
  • Ideality_hunter
  • Ideality_hunter
  • 2017-05-27 17:17:25
  • 363

原子操作在多核编程中的使用

 现代操作系统中,一般都提供了原子操作来实现一些同步操作,所谓原子操作,也就是一个独立而不可分割的操作。在单核环境中,一般的意义下原子操作中线程不会被切换,线程切换要么在原子操作之前,要么在原子操作完...
  • yuntongsf
  • yuntongsf
  • 2009-11-09 13:34:00
  • 1134

ARM体系结构中原子操作 ATOMIC 的实现

关于整数 的原子操作,对于Atomic_t类型,一直以来,记得书上说的都是要不CPU体系结构本身支持简单的原子操作,要不提供了锁内存总线功能,可以在操作期间,防止对数据的访问发生。今天突然想到,ARM...
  • colorant
  • colorant
  • 2007-04-24 15:58:00
  • 8067

锁(一) 中断屏蔽 原子操作

中断屏蔽 单cpu,在单cpu范围内避免竞态的简单方法是在进入临界区之前屏蔽系统的中断。cpu一般都具备屏蔽中断和打开中断 的功能,这项功能可以保证正在执行的内核执行路径不被中断处理程序抢占,防止某些...
  • MEIYOUDAO_JIUSHIDAO
  • MEIYOUDAO_JIUSHIDAO
  • 2017-04-27 10:38:11
  • 411

用汇编实现原子操作

原子操作(1) - 用汇编实现原子操作 “最轻量级的锁”,通常也叫”原子操作”,之所以加引号是因为他们在汇编级别并不是原子操作,是用多条指令完成的,这些操作大多都是利用CPU支持的汇编指令.在某些构...
  • zacklin
  • zacklin
  • 2012-04-10 14:46:02
  • 1576

C++小品:榨干性能:C++11中的原子操作(atomic operation)

所谓的原子操作,取的就是“原子是最小的、不可分割的最小个体”的意义,它表示在多个线程访问同一个全局资源的时候,能够确保所有其他的线程都不在同一时间内访问相同的资源。也就是他确保了在同一时刻只有唯一的线...
  • abcd1f2
  • abcd1f2
  • 2015-11-03 13:36:06
  • 1221

深入浅出java原子操作

原文地址:深入浅出java原子操作作者:opaljc 转自http://www.blogjava.net/xylz/archive/2010/07/04/325206.html part1 从...
  • zhuzhiyunzzy
  • zhuzhiyunzzy
  • 2014-04-08 15:16:29
  • 1583

6.1 原子操作

http://www.epubit.com.cn/book/onlinechapter/5563 6.1 原子操作 深入解析Android 5.0系统 6.1 原...
  • hintonic
  • hintonic
  • 2017-12-11 16:08:29
  • 97

linux内核同步之每CPU变量、原子操作、内存屏障、自旋锁

linux内核中的各种“任务”都能看到内核地址空间,因而它们之间也需要同步和互斥。linux内核支持的同步/互斥手段包括: 技术 功能 作用范围 每CPU变量 ...
  • chinazhangzhong123
  • chinazhangzhong123
  • 2016-06-26 01:02:01
  • 499

x86平台读取cpu支持sse2指令集的代码,以及原子操作的代码

// This module gets enough CPU information to optimize the // atomicops module on x86. #include ...
  • hintonic
  • hintonic
  • 2014-01-16 16:54:20
  • 955
收藏助手
不良信息举报
您举报文章:CPU中的原子操作
举报原因:
原因补充:

(最多只允许输入30个字)