硬件对同步的支持-TAS和CAS指令
现在主流的多处理器架构都在硬件水平上提供了对并发同步的支持。
今天我们讨论两个很重要的硬件同步指令:Test-and-Set和Compare-and-Swap
Test and Set
一个Test-and-Set(TAS)指令包括两个子步骤,把给定的内存地址设置为1,然后返回之前的旧值。
这两个子步骤在硬件上实现为一个原子操作,执行期间不会被其他处理器打断。
(一个CPU可以使用诸如Dual-port RAM电子原件提供的TAS指令,此外,CPU自身也可以提供CAS指令)
值得注意的是,TAS指令是在1位(bit)上实现,这限制了变量非0即1,不会有其他值,并且TAS总是把变量设置为1。
可见,TAS生而为自旋锁,下面是使用TAS实现自旋锁的伪代码[2]:
lock = 0 //shared state
while(test_and_set(lock)==0){ //try lock
//do nothing
}
// 临界区代码
lock = 0 //release
当第一个线程执行这段代码时,TAS指令会立即把lock设置为1,并返回0 ,线程退出while循环进入临界区。
如果另一个线程尝试进入临界区,TAS会把lock设置为1,但是也会返回1(由第一个线程的TAS指令设置为1),
此时第二个线程会一直while循环(忙等待),直到第一个线程退出临界区代码,执行了lock=0,即释放了锁。
这种通过while-loop等待获取锁的实现称为自旋锁(spin lock)。
Compare and Swap
compare-and-swap(CAS)指令和TAS指令类似,但是比TAS要更复杂。
与TAS只有一个参数不同,CAS指令需要三个参数,一个内存位置(V)、一个期望旧值(A)、一个新值(B)。
CAS指令的执行过程:
1.比较内存V的值是否与A相等?
2.如果相等,则用新值B替换内存位置V的旧值
3.如果不相等,不做任何操作。
4.无论哪个情况,CAS都会把内存V原来的值返回。
伪代码:
int CAS(int *ptr,int oldvalue,int newvalue)
{
int temp = *ptr;
if(*ptr == oldvalue)
*ptr = newvalue
return temp;
}
以上过程在CAS指令中是原子操作。
CAS支持32bit/64bit的数据类型,这使得CAS能够实现一些更复杂的自旋锁。
使用CAS实现线程安全的数据结构。
我们使用CAS实现一个并发的平衡二叉搜索树。[1]
基本思路是,所有的更新操作都要在二叉树的副本上进行,更新完成后,使用CAS指令把新的根节点引用替换旧的引用。
//共享变量
root = pointer to the root of the tree
//插入操作
do
old_root = root
new_root = new Tree
# copy old_root into new_root
# do insertion into new_root
until compare_and_swap (root, old_root, new_root) == old_root
平衡操作:
do
old_root = root
new_root = balanced_copy_of (old_root)
until compare_and_swap (root, old_root, new_root) == old_root
如果并行的执行平衡操作和插入操作,插入操作完成后会把二叉树的根节点指向新的引用。
等到平衡操作完成后,compare_and_swap将会失败,因为此时根节点指向了插入操作产生的新地址,不再等于old_root,
平衡操作会重复循环执行,直到成功更新根节点。
同样的,如果平衡操作先于插入操作完成,插入操作的CAS指令也会失败(根节点已指向平衡操作产生的新地址),然后插入操作重复循环,直到成功。
基于CAS指令可以实现基础的信号量、互斥量之外,还可以实现更复杂的lock-free和wait-free算法。
延伸阅读:
1.康奈尔大学操作系统课件:Architectural support for synchronization
2.wiki:Test-and-Set指令
3.wiki:Compare-and-swap指令
4.TAS vs CAS
硬件对同步的支持-TAS和CAS指令的更多相关文章
- Confluence 6 从外部目录中同步数据支持的目录类型
针对一些特定的用户目录类型,Confluence 在系统的数据库中保存了目录的缓存信息(用户和用户组),这样能够让系统更快速的访问用户和用户组数据.一个数据同步的进程将会间歇性的在系统中运行来将远程的 ...
- CAS指令
原文链接:https://www.jianshu.com/p/00edb3d74a33 CAS是CPU的一条指令,其具有原子性,原子性是由CPU硬件层面保证的. CAS原语有三个操作数--内存 ...
- 从ObjectPool到CAS指令
相信最近看过我的文章的朋友对于Microsoft.Extensions.ObjectPool不陌生:复用.池化是在很多高性能场景的优化技巧,它能减少内存占用率.降低GC频率.提升系统TPS和降低请求时 ...
- 【PC桌面软件的末日,手机移动端App称王】写在windows11支持安卓,macOS支持ios,龙芯支持x86和arm指令翻译
面对这场突如其来的变革,作为软件开发者,应该如何选择自己今后的发展方向?桌面软件开发领域还有前景吗? 起源 自从苹果发布m1处理器,让自家Mac支持IOS移动端app运行之后,彻底打破了移动端app和 ...
- CAS(硬件CPU同步原语)
CAS有3个操作数.内存值V,旧的预约值A,要修改后的新值B.当且仅当预期值A和预期值V相同时,将内存值V修改为新值B.当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做. 应用1. ...
- 定时自动同步文件,支持多文件夹同步,支持过滤文件和文件夹,解决FileSystemWatcher多次文件触发事件(源码)
博客园里面有很多同步工具和软件,关于FileSystemWatcher类解释的也很多,但收集了很多文章后,感觉没好的方法,自己没事写了一个定时文件同步,借鉴了很多博客园朋友的东西: 上主菜: 配置文件 ...
- Netty的并发编程实践3:CAS指令和原子类
互斥同步最主要的问题就是进行线程阻塞和唤醒所带来的性能的额外损耗,因此这种同步被称为阻塞同步,它属于一种悲观的并发策略,我们称之为悲观锁.随着硬件和操作系统指令集的发展和优化,产生了非阻塞同步,被称为 ...
- 《java并发编程实战》读书笔记12--原子变量,非阻塞算法,CAS
第15章 原子变量与非阻塞同步机制 近年来,在并发算法领域的大多数研究都侧重于非阻塞算法,这种算法用底层的原子机器指令(例如比较并交换指令)代替锁老确保数据在并发访问中的一致性. 15.1 锁的劣势 ...
- .NET机器学习 ML.NET 1.4预览版和模型生成器更新
ML.NET 是面向.NET开发人员的开源和跨平台机器学习框架. ML.NET 还包括Model Builder (一个简单的UI工具)和 CLI ,使用自动机器学习(AutoML)构建自定义 ...
随机推荐
- 循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用
在我们开发BS页面的时候,往往需要了解常规界面组件的使用,小到最普通的单文本输入框.多文本框.下拉列表,以及按钮.图片展示.弹出对话框.表单处理.条码二维码等等,本篇随笔基于普通表格业务的展示录入的场 ...
- 一文说通Dotnet Core的中间件
前几天,公众号后台有朋友在问Core的中间件,所以专门抽时间整理了这样一篇文章. 一.前言 中间件(Middleware)最初是一个机械上的概念,说的是两个不同的运动结构中间的连接件.后来这个概念 ...
- JAVASE(十二) Java常用类: 包装类、String类、StringBuffer类、时间日期API、其他类
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.包装类 1 .1 八个包装类 1. 2 基本数据类型,包装类,String者之间的转换 2. ...
- Java实现 LeetCode 445 两数相加 II
445. 两数相加 II 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会 ...
- Java实现 蓝桥杯VIP 算法训练 校门外的树
问题描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,--,L,都种 ...
- java实现机器人行走
某少年宫引进了一批机器人小车.可以接受预先输入的指令,按指令行动.小车的基本动作很简单,只有3种:左转(记为L),右转(记为R),向前走若干厘米(直接记数字). 例如,我们可以对小车输入如下的指令: ...
- Java实现第九届蓝桥杯打印大X
打印大X 题目描述 如下的程序目的是在控制台打印输出大X. 可以控制两个参数:图形的高度,以及笔宽. 用程序中的测试数据输出效果: (如果显示有问题,可以参看p1.png) 高度=15, 笔宽=3 * ...
- ArrayDeque使用&实现原理分析
ArrayDeque使用&实现原理分析 学习Okhttp实现源码时,发现其任务分发时用到了ArrayDeque.因此了解一下ArrayDeque的使用方式和实现原理. 一.Deque dequ ...
- react后台管理系统路由方案及react-router原理解析
最近做了一个后台管理系统主体框架是基于React进行开发的,因此系统的路由管理,选用了react-router(4.3.1)插件进行路由页面的管理配置. 实现原理剖析 1.hash的方式 ...
- Java—JDBC向mysql数据库中给某个表添加数据时,会遇到的问题,如下
解析(jar包该放在那里,以及其它的操作): 把jar包(驱动)添加到自己的项目中,最好新建一个文件夹,再把jar包(驱动包)添加到这个所新建的文件中 1.先建好自己的项目,再新建一个文件夹,如下: ...