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 ...
随机推荐
- Qt4.8.5 QtWebKit QWebView 用户栈检查崩溃问题的思考
最近在项目中,发现在使用Qt4.8.5 提供的QWebView与网页交互的时候, m_pWebView->page()->mainFrame()->evaluateJavaScrip ...
- CSS3 结构伪类选择器 详解
1 CSS3 结构伪类选择器 1.E:root 匹配E元素所在的根元素 即:html 2. E:nth-child(n) (1)匹配E元素的父元素中第n个子元素,(2)且该位置的子元素类型必须是E类型 ...
- CSS3转换
一.2D转换 1.css3 rotate()旋转 通过指定的角度参数对原元素指定一个2D rotation(2D 旋转) 语法: transform:rotate(<angle>); ...
- Struts框架——(二)Struts原理with登录实例
二. Struts基本工作流程 假设现在有以下情景: 用户正在浏览一个用STRUTS的技术构建的网站主页,主页上有个登陆表单,用户填好登陆名和密码,单击"登陆"按钮,就激活了以下一 ...
- css中clip-path属性的运用
今天看到一位同学的需求,要在一个div中加一个小尖尖,对话时发的图片,旁边这个三角是怎么实现与图片的颜色一致,效果如下: 当然,解决这个问题有各种奇淫巧技,现在我们来看一个css属性clip-path ...
- javascript:history.go()和History.back()的区别
http://www.mikebai.com/Article/2009-11/757.html
- 图片缩放应用(nearest / bilinear / three-order interpolate)
typedef xPixel PIXELCOLORRGB; double Sinxx(double value){ if (value < 0) value = -value; if (valu ...
- JavaWeb 学习007-4个页面,5条sql语句(添加、查看、修改、删除)2016-12-2
需要复习的知识: 关联查询 =================================================================================班级模块学 ...
- asp.net Word Document Open return null
- CS0012: 类型“System.Data.Objects.DataClasses.EntityObject”在未被引用的程序集中定义
entity framework,没在view引用 实体对象时,一直没问题,引用后爆出这个错误来 CS0012: 类型"System.Data.Objects.DataClasses.En ...