lockfree
为什么要lockfree
按我的理解, lockfree就是不去 调用操作系统给定的锁机制.
1. 会有system call, and system call is expensive; 比如pthread在linux里调用了futex.
2. 会失去控制, 接下来发生什么看操作系统心情了.
怎么做lockfree
不用操作系统给定的 同步机制, 而使用 硬件提供的机制, 简单说, 就是对 机器指令 的封装函数(right?).
首先一个是 compare-and-set. CAS/TAS
保证对某个变量的读出和修改是 原子的. 如下:
typedef LONG volatile tsl_t; #define MUTEX_SET(tsl) (!InterlockedExchange((PLONG)tsl, 1))
#define MUTEX_UNSET(tsl) InterlockedExchange((PLONG)tsl, 0)
`MUTEX_SET`返回1 表示已经锁住:
若此时 `tsl`为1, 表示已经被锁了, 置`tsl`为1, 返回原值的!, 即为0;
若此时 `tsl`为0, 表示锁可用, 置`tsl`为1, 返回1, 成功.
`MUTEX_SET`会被放入一个 loop中不断重试. 在gcc中, 可以用类似 `__sync_bool_compare_and_swap`的原语:
https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html
对应不同的硬件/编译器, 可以使用的cas不同. 例子: bdb: mutex_int.h. wiredtiger: gcc.h/msvc.h
memory barrier解决乱序
出于性能考虑, 编译器/硬件 会 reorder execution of your program. 对单线程程序 完全没有影响, 多线程就不行了.
编译器会reorder: 这个算内部矛盾? 毕竟都是软件的事
硬件(cpu) 会reorder: 对cpu来说, 数据放在三个地方: 寄存器/cpu缓存/主存.
LOAD - 从主存读入 到寄存器/缓存
STORE - 从寄存器/缓存 写入主存
本来 有 MESI - 缓存一致性协议(cache coherency) 保证 缓存-主存的一致性的:
https://en.wikipedia.org/wiki/MESI_protocol
modified - exclusive - shared - invalid
MESI是一个理论上的东西. 在实现上, 从性能考虑, 加入 store buffers, invalidate queues.
store buffer:
要解决的问题: 写一个shared/invalid cache line, 先广播 read-invalid message, 让别的处理器都invalid, 返回Invalidate Acknowledge, 然后才能写入cache.
解决方案:可以写入store buffer, 广播, 当前processor 接着做别的. 等收到所有处理器都invalid完了, 返回Invalidate Acknowledge, , 在写入cache. (异步执行的意思?)
给程序带来的新问题: write离开 buffer的时间 和 异步执行有关. 和程序原order无关.
invalidate queue:
要解决的问题: invalid 一个cache line挺慢的; 万一store buffer满了, processor 需要等待 某write释放 才能继续.
解决方案: 把 invalid 请求 入queue, 立即发送Invalidate Acknowledge, 然后慢慢执行queue. (还是异步?)
给程序带来的新问题:
Memory Barrier:
A store barrier will flush the store buffer, ensuring all writes have been applied to that CPU's cache.
A read barrier will flush the invalidation queue, thus ensuring that all writes by other CPUs become visible to the flushing CPU.
在做下一次store前, 保证store buffer被处理完 - membar之前的写 全部在cache里;
在做下一次load前, 保证invalidation queue被处理完 - 保证cache中没有过期数据.
full membar
read membar: flush invalidation queue
write member: flush store buffer
LFENCE/SFENCE/MFENCE
acquire/release
LoadLoad/LoadStore/StoreLoad/StoreStore: sparc
volatile: 对c来说, 用于阻止编译器过度优化. 如 替换 循环变量为 `while(true)` -- (这个我见过!); 改内存访问为 寄存器访问等.
http://lwn.net/Articles/250967/
http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_11
http://www.puppetmastertrading.com/images/hwViewForSwHackers.pdf
lockfree的更多相关文章
- Lock-Free 编程
文章索引 Lock-Free 编程是什么? Lock-Free 编程技术 读改写原子操作(Atomic Read-Modify-Write Operations) Compare-And-Swap 循 ...
- Lock,LockFree,MemoryBarrier,ConcurrentCollection
最近看并行编程书本的一些心得,简单记录下多线程和并行编程必知必会的几个概念,再次加深自己的理解. .NET Framework4提供了一个新的命名空间System.Collections.Concur ...
- 无锁数据结构(Lock-Free Data Structures)
一个星期前,我写了关于SQL Server里闩锁(Latches)和自旋锁(Spinlocks)的文章.2个同步原语(synchronization primitives)是用来保护SQL Serve ...
- 使用C++11实现无锁stack(lock-free stack)
前几篇文章,我们讨论了如何使用mutex保护数据及使用使用condition variable在多线程中进行同步.然而,使用mutex将会导致一下问题: 等待互斥锁会消耗宝贵的时间 — 有时候是很多时 ...
- Boost Lockfree
Boost Lockfree flyfish 2014-9-30 为了最大限度的挖掘并行编程的性能考虑使用与锁无关的数据结构来编程 与锁无关的数据结构不是依赖于锁和相互排斥来确保线程安全. Lockf ...
- 并发编程(三): 使用C++11实现无锁stack(lock-free stack)
前几篇文章,我们讨论了如何使用mutex保护数据及使用使用condition variable在多线程中进行同步.然而,使用mutex将会导致一下问题: 等待互斥锁会消耗宝贵的时间 - 有时候是很多时 ...
- boost::lockfree::queue多线程读写实例
最近的任务是写一个多线程的东西,就得接触多线程队列了,我反正是没学过分布式的,代码全凭感觉写出来的,不过运气好,代码能够work= = 话不多说,直接给代码吧,一个多消费者,多生产者的模式.假设我的任 ...
- 【Java并发编程】2、无锁编程:lock-free原理;CAS;ABA问题
转自:http://blog.csdn.net/kangroger/article/details/47867269 定义 无锁编程是指在不使用锁的情况下,在多线程环境下实现多变量的同步.即在没有线程 ...
- 读Lock-Free论文实践
论文地址:implementing Lock-Free Queue 论文大体讲的意思是:Lock-Base的程序的performance不好,并且a process inside the critic ...
随机推荐
- spring mvc 第三天【注解实现springmvc Handler返回值为Object 的配置】
这里使用的是在前台发起请求Handler,后台伪造数据响应给前台, 解决方案:将之前的viewResolver抹掉,配置对应(request)请求的Handler信息如下 之前Handler返回的都直 ...
- cinder节点部署
其实看基础理论篇大家也可以看出来,cinder跟nova流程比较像,是这样的,nova为云主机提供了虚拟资源,cinder则是提供存储相关的资源,cinder的小伙伴叫swift,不过这个一般没人用了 ...
- iOS常用网络库之AFNetWorking
简介 `AFNetworking`是iOS开发网络API中最常用的第三方库,`github`中的`star`数充分说明了它在iOS开发中第三方库中的江湖地位 github地址:[AFNe ...
- bootstrap 时间控件带(时分秒)选择器
1.控件下载地址:http://www.bootcss.com/p/bootstrap-datetimepicker/index.htm,参数设置说明也在这个链接下面: 2.具体参数说明(复制原链接) ...
- Java数据类型转换
一.Date与String相互转换 1.Date转换成String SimpleDateFormat dd = new SimpleDateFormat("yyyy-MM-dd HH:mm& ...
- oracle去掉重复记录语句
oracle去掉重复记录语句 比如现在有一人员表 (表名:peosons) 若想将姓名.身份证号.住址这三个字段完全相同的记录查询出来 select p1.* from persons p1 ...
- iOS 自定义图片和文字垂直显示按钮<上面是图片,文字显示下面>
#import <UIKit/UIKit.h> @interface VerticalButton : UIButton @end #import "VerticalButton ...
- Hibernate持久化类属性映射
Hibernate充当应用程序和数据库之间的中间件,实现二者之间的交互操作,他对JDBC进行了封装,以完全面向对象的方式来操作数据. 适用于有多个数据源的情况下,不必去考虑不同数据源的操作差异. Hi ...
- Eclipse 配置 pyDev(转)
转自:http://www.51testing.com/html/75/534775-859092.html 很久没有接触到Python了.以前都是在用2.7版本的,这次索性就安装3.2的了.一般的小 ...
- Python模块:itertools
itertools模块:循环器 一,无穷循环器:count,cycle,repeat (1)count(5,3) #从5开始的整数循环器,每次增加3,即:5,8,11,14,17... from it ...