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 ...
随机推荐
- MySQL 5.7版本sql_mode=only_full_group_by问题
用到GROUP BY 语句查询时com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #2 of SELECT l ...
- Wordpress上传到阿里云服务器
Wordpress上传到阿里云服务器 登录服务器 https://account.aliyun.com/login/login.htm 绑定域名 获取FTP信息.数据库信息 在本地修改wordpres ...
- webservice 接口通过 HTTP 获取数据
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Ne ...
- JavaScript学习(一)—处理事件2
下面的表中为最常用的 12 种 JavaScript 事件处理程序. 一.处理窗口事件(onload事件,onunload事件,onresize事件,onmove事件,onabort事件,onerro ...
- Android开发学习---使用Intelij idea 13.1 进行android 开发
1.为什么放弃eclipse?太卡!! 实在受不了eclipse的卡了,运行WEB项目还好,但android开发实在太慢,太慢!经常卡死,CPU经常被占满! 看网上很多人都说比Intelij idea ...
- js基础到精通全面教程--JS教程
适合阅读范围:对JavaScript一无所知-离精通只差一步之遥的人 基础知识:HTML JavaScript就这么回事1:基础知识 1 创建脚本块 1: <script language=”J ...
- aspx页面调用发送邮件验证码(结合前两篇)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs ...
- 在Linux上配置xampp后远程访问域名报错
在Linux上配置xampp后远程访问域名报错: New XAMPP security concept: Access to the requested object is only availabl ...
- 【Docker 在 windows 10 / windows 8 下安装】
步骤: 1. 下载: a.https://github.com/boot2docker/windows-installer/releases 下载一个 windows 客户端: 安装时建议勾选:Boo ...
- Verilog经典输入控制/激励信号模板1
:]i; always @ ( posedge CLOCK or negedge RESET ) if( !RESET ) begin i <= 'd0; Start_Si ...