Locked Atomic Operations

32位的IA-32处理器支持对系统内存中的位置执行“加锁的原子操作”。这些操作通常用于管理共享的数据结构(例如信号量,段描述符,系统段,或者页表)。两个或多个处理器可能会同时修改其中的某些域或者标志。处理器使用3种互相依赖的机制来实现加锁的原子操作:

  • 受保障的原子操作
  • 总线封锁,使用LOCK#信号和LOCK指令前缀
  • 缓存一致性协议,确保可以对缓存中的数据结构执行原子操作,被称为缓存封锁(cache lock);这种机制适用于P6,Pentium 4,Intel Xeon(及其以后)系列处理器

这些操作主要在以下几个方面互相依赖。

某些基本的访存事务(例如从存储器中读或写一个字节)总是受保障的原子操作。换句话说,一旦事务启动,处理器保证在 本次事务完成之前,不会有其他的处理器或者总线代理(bus agent)被允许访问同一个存储器地址。

处理器还支持对某些选中的访存操作(例如对存储器中的共享区域执行读-改-写操作)执行“带总线封锁”的原子操作。从业务逻辑上看,对这些区域的访问应该是原子性的,但是处理器并不会自动地执行原子操作。所以需要在指令代码中明确指出(即使用lock指令前缀)。

在现代处理器上,频繁使用的存储器数据通常会被缓存在处理器的L1或者L2缓存中,原子操作通常直接作用在处理器的缓存中,无需断言总线封锁(assert bus lock,注:这里指不需要使用CPU的LOCK#引脚,在指令代码中还是需要lock前缀的。)

注意:

当有竞争的加锁访问时,软件需要实现自己的算法,确保对资源的公平访问,以避免锁饥饿或饿死。硬件没有提供任何资源用于确保参与者之间的公平竞争。管理信号量和互斥锁功能的公平性是软件的责任。

随着IA-32处理器复杂性增加,加锁的原子操作机制也相应的跟着演化。相比起早期的处理器,比较新的IA-32处理器(P6,Pentium 4,Intel Xeon系列)和Intel 64处理器提供了更加精细化的加锁机制。下面详细的讨论这些机制。

Guaranteed Atomic Operation

Intel486及其后代处理器确保如下的基本操作总是自动原子性(即无需程序员编写任何指令)的:

  • 读/写单个字节
  • 读/写按16位对齐的单字
  • 读/写按32位对齐的双字

Pentium及其后代处理器确保如下的访存操作总是原子性的:

  • 读/写按64位对齐的四字
  • 访问非缓存类型存储器(uncached memory)中16位宽的数据且数据的16个比特位必须能够容纳在32位的数据总线中。参看下图

P6及其后代处理器确保如下的访存操作总是原子性的:

  • 访问缓存的存储器(cached memory)中非对齐的16-,32-,和64-位宽的数据且数据的比特位必须能够容纳在同一个缓存行中。

在Intel Core 2 Duo,Intel Atom™,Intel Core Duo,Pentium M,Pentium 4,Intel Xeon,P6 family,Pentium,和Intel486处理器上,对于可缓存的存储器区域,访问跨缓存行或者跨页面边界的数据不保证是原子性的。在Intel Core 2 Duo,Intel Atom,Intel Core Duo, Pentium, Pentium 4, Intel Xeon,和P6 family处理器上,通过总线控制信号可以允许外部内存子系统将跨界访问(split access)变成原子性的;但是,非对齐的数据访问会严重的影响处理器性能,应该要避免。

x87指令或者SSE指令都有可能访问超过4字(即8字节)宽度的数据,这种访问有可能需要多次存储器访问操作。如果将如此长的数据写入内存,某次操作可能已经完成内存写入,但是后续写存操作可能由于架构原因(例如页表入口被标记为“不存在”,即内存缺页)还未完成。在这种情况下,尽管整条指令出现故障,尚未执行完毕,但是部分数据(写存完成的那次操作)可能已经对软件可见了。如果TLB的无效化invalidation操作由于某种原因被延迟的,即便是同一个存储器页面访问,也可能发生缺页故障。

Intel 64/x86_64/IA-32/x86处理器 - 锁原子操作(1) - 处理器保证的原子操作相关推荐

  1. Intel 64/x86_64/IA-32/x86处理器 - 锁原子操作(2) - 总线封锁/缓存封锁

    Bus Locking Intel 64和IA-32处理器提供了LOCK#信号,在某些关键的访存操作时会自动地激活assert这个信号,用于封锁系统总线或类似的链接.当这个输出信号被激活时,就会阻塞来 ...

  2. Intel 64/x86_64/IA-32/x86处理器基本执行环境 (1) - 32位执行环境概述

    Basic Execution Environment Overview IA-32处理器提供了一套完整的资源,在处理器上运行的程序/任务可以执行指令,存储代码,数据以及状态信息.这些资源(如下简要的 ...

  3. Intel 64/x86_64/IA-32/x86处理器 - SIMD指令集 - SSE扩展(1) - 概述/历史/新数据类型/XMM寄存器组

    SSE Instructions SSE Overview & History Intel SSE技术的全称是Streaming SIMD Extension,中文译作流式单指令多数据指令扩展 ...

  4. Intel 64/x86_64/IA-32/x86处理器指令集 - CPUID (2) - 起源

    CPUID Origination 随着Intel处理器架构的演进与更新换代(8086,8088,Intel286,Intel386™,Intel486™和Pentium™处理器),提供一套完善的方法 ...

  5. Intel 64/x86_64/x86/IA-32处理器操作模式/运行模式

    Processor Operation Mode IA-32架构支持3种操作模式,和一种类操作模式(quasi-operating mode): 实地址模式/实模式(real-address mode ...

  6. Intel 64/x86_64/IA-32/x86处理器 - SIMD指令集 - SSE扩展(7) - 混洗指令 解组合指令

    SSE Shuffle and Unpack Instructions SSE的混洗指令与解组合指令混洗shuffle或交错interleave单精度浮点操作数,并将结果保存到目标操作数. 指令 描述 ...

  7. Intel 64/x86_64/IA-32/x86处理器 - SIMD指令集 - MMX技术(1) - 概述 传输指令

    MMX™ Instructions IA-32架构引入了4个指令集扩展,使得IA-32处理器可以执行单指令多数据SIMD操作.这些扩展包括MMX技术,SSE扩展,SSE2扩展,SSE3扩展. MMX指 ...

  8. Intel 64/x86_64/IA-32/x86处理器 - 通用指令(1) - 数据传输指令

    General-Purpose Instructions 通用指令执行基本的数据搬移,算术/逻辑计算,程序流控制,字符串操作等.这些指令被频繁地用于运行在IA-32与Intel 64架构的系统软件与应 ...

  9. Intel 64/x86_64/x86/IA-32处理器串行化指令(1) - 概述

    Serializing Instructions 注:串行化指令的概念非常容易理解,但是要用好(在哪里用,何时用)则需要深厚的处理器架构和流水线乱序执行的功底.好在大部分应用程序不会用到这类指令. I ...

最新文章

  1. 【图灵】iOS技能书单——入门+进阶+精通
  2. 论怎么写好一篇实验报告
  3. 【晒出你的第83行代码】阿里研究员福贝,用一个小演示程序来解释一下 C++11/14 里的 closure 是可以多么的“爽”...
  4. SimpleMembership
  5. 手工做迷宫_好玩易上手的自然探索实验,春天必备,宅家就能带孩子做起来!...
  6. 比赛-暑假训练赛1 (26 Jul, 2018)
  7. bzoj1237 [SCOI2008]配对 贪心结论+插数dp
  8. GoLand连接Linux子系统远程开发
  9. 操作系统课设 Nachos 实验六、七、八:Nachos 用户程序与系统调用、地址空间的扩展、系统调用 Exec() 与 Exit()
  10. 如何解决python 画图时 it could not find or load the Qt platform plugin “windows“ in “”的问题
  11. Java动态数组的实现
  12. Ubuntu安装Microsoft Windows Fonts微软字体库
  13. Python语言程序设计基础-题库
  14. Intent启动拨号盘,实现打电话功能
  15. C语言入门 | c语言基础知识
  16. post请求https安全证书问题
  17. pdf文件转bitmap再转图片
  18. 360搜索“触链”聚焦版权领域,“图刻”是噱头还是不忘安全初心?
  19. 用python做flash动画_6 款用于创建优秀动画的免费 Flash 编辑器
  20. 灵魂画手之——天堂鸟

热门文章

  1. 【numpy】numpy.zeros()函数
  2. 蔚来测开提前批面试(一面)
  3. LeetCode-105:从前序与中序遍历序列构造二叉树
  4. c++编写手机小游戏代码_玩过自己开发的贪吃蛇吗?点这里,教你用Python写一个贪吃蛇小游戏!(附源代码)...
  5. MySQL模糊查询的那些谣言
  6. 避免使用GroupByKey
  7. 相对、绝对、固定定位,以及其层级关系和脱离文档流的影响
  8. cassandra随机获取数据_Cassandra维护最终一致性 和存储机制 分区策略
  9. ssh 连接_Docker实战——使用SSH连接docker容器
  10. python统计行号_用Python实现两个文件的不同行的编号