小结: 1. 很多时候,编译器和 CPU 引起内存乱序访问不会带来什么问题,但一些特殊情况下,程序逻辑的正确性依赖于内存访问顺序,这时候内存乱序访问会带来逻辑上的错误, 2. https://github.com/torvalds/linux/blob/master/Documentation/memory-barriers.txt#L111 ============================ ABSTRACT MEMORY ACCESS MODEL ===================…
DPDK 无锁环形队列(Ring) 此篇文章主要用来学习和记录DPDK中无锁环形队列相关内容,结合了官方文档说明和源码中的实现,供大家交流和学习. Author : Toney Email : vip_13031075266@163.com Date : 2020.11.8 Copyright : 未经同意不得转载!!! version : dpdk-2.2.0 文章目录 DPDK 无锁环形队列(Ring) @[TOC] 1. DPDK中的环形数据结构 2. 环形队列:单生产者/单消费者模式 2…
Linux 内核:匠心独运之无锁环形队列 Kernel version Linux 2.6.12   Author Toney   Email vip_13031075266@163.com   Date 2020.11.8   目录 Linux 内核:匠心独运之无锁环形队列 1. 前言 2. Kfifo简介 3. Kfifo初始化 3.1 判断一个数是否为2的幂次方 3.2 求不小于某个数2的整数次幂 3.3 为什么要求2的幂次方呢? 4. Kfifo入队和出队 4.1 Kfifo右侧入队 4…
无锁环形队列 1.Ring_Queue在payload前加入一个头,来表示当前节点的状态 2.当前节点的状态包括可以读.可以写.正在读.正在写 3.当读完成后将节点状态改为可以写,当写完成后将节点状态改为可以读 4.Ring_Queue使用时参照生产者消费者模型,生产者生产(写)一个可用节点,消费者获得(读)队列头节点 Github地址: https://github.com/HITFishily/CandCPP /****************************************…
原文:https://www.cnblogs.com/my_life/articles/5220172.html Memory barrier 简介 程序在运行时内存实际的访问顺序和程序代码编写的访问顺序不一定一致,这就是内存乱序访问.内存乱序访问行为出现的理由是为了提升程序运行时的性能.内存乱序访问主要发生在两个阶段: 编译时,编译器优化导致内存乱序访问(指令重排) 运行时,多 CPU 间交互引起内存乱序访问 Memory barrier 能够让 CPU 或编译器在内存访问上有序.一个 Mem…
转自:http://name5566.com/4535.html 参考文献列表:http://en.wikipedia.org/wiki/Memory_barrierhttp://en.wikipedia.org/wiki/Out-of-order_executionhttps://www.kernel.org/doc/Documentation/memory-barriers.txt 本文例子均在 Linux(g++)下验证通过,CPU 为 X86-64 处理器架构.所有罗列的 Linux 内…
理解 Memory barrier(内存屏障) 发布于 2014 年 04 月 21 日2014 年 05 月 15 日 作者 name5566 参考文献列表:http://en.wikipedia.org/wiki/Memory_barrierhttp://en.wikipedia.org/wiki/Out-of-order_executionhttps://www.kernel.org/doc/Documentation/memory-barriers.txt 本文例子均在 Linux(g+…
我不想卷,我是被逼的 在做了几年前端之后,发现互联网行情比想象的差,不如赶紧学点后端知识,被裁之后也可接个私活不至于饿死.学习两周Go,如盲人摸象般不知重点,那么重点谁知道呢?肯定是使用Go的后端工程师,那便利用业余时间找了几个老哥对练一下.其中一位问道在利用多个goroutine发送请求拿到结果之后如果进行销毁.是个好问题,研究了一下需要利用Context,而我一向喜欢研究源码,继续深挖发现细节非常多,于是乎有此这篇文章. 有句话叫做初出茅庐天下无敌,再练三年寸步难行.本着不服输精神回来研究了…
并发编程 memory barrier (内存栅栏) CPU级 1.CPU中有多条流水线,执行代码时,会并行进行执行代码,所以CPU需要把程序指令 分配给每个流水线去分别执行,这个就是乱序执行: 2.CPU中有read buffer/ write buffer 这2个读写缓存,这2个部件用于缓存CPU对内存的读写操作,并不是实时同步到CPU缓存(L1/L2/L3),这个就会导致更新一块内存后,其他CPU感知不到: 读取的时候,优先到read buffer找数据,找到了,就用这个数据了,如果这时内…
目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的艺术 [续] 无锁队列 第一篇文章末尾我们提到的<无锁队列的实现>(陈皓(hào)),该文末尾提到的“用数组实现无锁队列”,即用 RingBuffer 实现的无锁队列: RingBuffer 是一个很好的东西,用在无锁/有锁队列实在是太棒了,如该文提到的一样,RingBuffer由于使用的是序号(…
目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的艺术 [续] 开篇 这几天研究了一下 disruptor .Net版,由于.Net版跟进不及时,网上只有 v2.10 版.没仔细研究,但可以肯定的是跟最新的Java版 disruptor 3.30 是有不少区别的.我也用这个 2.10 的.Net版本写了跟我们的问题相似的测试程序,得到的结果跟 Ja…
目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的艺术 [续] 开篇 这两天状态不是很好,我甚至把最新的<鹿鼎记>(梁栋版)快看完了,基本上是躺床上看的,其实不算好看,可能是太无聊了.不过我还是把 disruptor 大致看明白了,也修改了 disruptor 的测试代码,基本接近 RingQueue 的测试了.不过目前的测试结果跟 RingQu…
目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的艺术 [续] 开篇 这是第五篇的后续,这部分的内容同时会更新和添加在 第五篇:RingQueue(中) 休眠的艺术 一文的末尾. 归纳 紧接上一篇的末尾,我们把 Windows 和 Linux 下的休眠策略归纳总结一下,如下图: 我们可以看到,Linux 下的 sched_yield() 虽然包括了…
Linux kernel里面从来就不缺少简洁,优雅和高效的代码 比如,通过限定写入的数据不能溢出和内存屏障实现在单线程写单线程读的情况下不使用锁.因为锁是使用在共享资源可能存在冲突的情况下.还用设置buffer缓冲区的大小为2的幂次方,以简化求模运算,这样求模运算就演变为 (fifo->in & (fifo->size - 1)).通过使用unsigned int为kfifo的下标,可以不用考虑每次下标超过size时对下表进行取模运算赋值,这里使用到了无符号整数的溢出回零的特性.由于指…
本文例子均在 Linux(g++)下验证通过,CPU 为 X86-64 处理器架构.所有罗列的 Linux 内核代码也均在(或只在)X86-64 下有效. 本文首先通过范例(以及内核代码)来解释 Memory barrier,然后介绍一个利用 Memory barrier 实现的无锁环形缓冲区. Memory barrier 简介 程序在运行时内存实际的访问顺序和程序代码编写的访问顺序不一定一致,这就是内存乱序访问.内存乱序访问行为出现的理由是为了提升程序运行时的性能.内存乱序访问主要发生在两个…
本文转载自:http://name5566.com/4535.html 参考文献列表:http://en.wikipedia.org/wiki/Memory_barrierhttp://en.wikipedia.org/wiki/Out-of-order_executionhttps://www.kernel.org/doc/Documentation/memory-barriers.txt 本文例子均在 Linux(g++)下验证通过,CPU 为 X86-64 处理器架构.所有罗列的 Linu…
一直以来.I/O顺序问题一直困扰着我.事实上这个问题是一个比較综合的问题,它涉及的层次比較多,从VFS page cache到I/O调度算法,从i/o子系统到存储外设.而Linux I/O barrier就是当中重要的一部分. 可能非常多人觉得,在做了文件写操作后,调用fsycn就能保证数据可靠地写入磁盘.大多数情况下,确实如此. 可是,由于缓存的存在.fsycn这些同步操作.并不能保证存储设备把数据写入非易失性介质. 假设此时存储设备发生掉电或者硬件错误.此时存储缓存中的数据将会丢失.这对于像…
背景 同步基元分为用户模式和内核模式 用户模式:Iterlocked.Exchange(互锁).SpinLocked(自旋锁).易变构造(volatile关键字.volatile类.Thread.VolatitleRead|Thread.VolatitleWrite).MemoryBarrier. 内存屏障(英語:Memory barrier),也称内存栅栏,内存栅障,屏障指令等,是一类同步屏障指令,它使得 CPU 或编译器在对内存进行操作的时候, 严格按照一定的顺序来执行, 也就是说在内存屏障…
目录 1. 前言2 2. 结论2 3. volatile应用场景3 4. 内存屏障(Memory Barrier)4 5. setjmp和longjmp4 1) 结果1(非优化编译:g++ -g -o x x.cpp -O0) 5 2) 结果2(优化编译:g++ -g -o x x.cpp -O2) 6 6. 不同CPU架构的一致性模型6 7. x86-TSO7 8. C++标准库对内存顺的支持7 1) 头文件<stdatomic.h> 7 2) 头文件<atomic> 8 附1:…
=================                          LINUX内核内存屏障                          ================= By: David Howells <dhowells@redhat.com>     Paul E. McKenney <paulmck@linux.vnet.ibm.com> 译: kouu <kouucocu@126.com> 出处: Linux内核文档 -- Docum…
锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放.在上下文切换的时候,cpu之前缓存的指令和数据都将失效,对性能有很大的损失.操作系统对多线程的锁进行判断就像两姐妹在为一个玩具在争吵,然后操作系统就是能决定他们谁能拿到玩具的父母,这是很慢的.用户态的锁虽然避免了这些问题,但是其实它们只是在没有真实的竞争时才有效. Java在JDK1.5之前都是靠s…
一哥们翻译的boost的无锁队列的官方文档 原文地址:http://blog.csdn.net/great3779/article/details/8765103 Boost_1_53_0终于迎来了久违的Boost.Lockfree模块,本着学习的心态,将其翻译如下.(原文地址:http://www.boost.org/doc/libs/1_53_0/doc/html/lockfree.html) Chapter 17. Boost.Lockfree 第17章.Boost.Lockfree Ta…
本文首先介绍 Erlang 运行时中需要使用无锁队列的场合,然后介绍无锁队列的基本原理及会遇到的问题,接下来介绍 Erlang 运行时中如何通过“线程进度”机制解决无锁队列的问题,并介绍 Erlang 运行时中提供的一个通用无锁队列的实现及其在 ERTS 异步线程池中的应用. 无锁队列在 ERTS 中的应用场合 为了提升 Erlang 运行时在多核/众核处理器上的 scalability,Erlang 运行时使用了大量无锁数据结构,无锁队列(lock-free queue)就是其中广泛使用的一种…
转自:http://www.cnblogs.com/Mainz/p/3546347.html?utm_source=tuicool&utm_medium=referral 锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放.在上下文切换的时候,cpu之前缓存的指令和数据都将失效,对性能有很大的损失.操作系统对多线程的锁进行判断就像两姐妹在为一个玩具在…
两年多以前随手写了点与 lock free 相关的笔记:1,2,3,4,质量都不是很高其实(读者见谅),但两年来陆陆续续竟也有些阅读量了(可见剑走偏锋的技巧是多容易吸引眼球).笔记当中在解决内存释放和 ABA 问题时提到了 Hazard Pointer 这个东西,有两三个读者来信问这是什么,让详细讲一下,我想了想,反正以前在看这东西的时候也记了些东西,干脆整理一下发出来. 前面写的那几篇笔记都来源于 Maged Michael 的学术论文,Hazard pointer 也是他的创想,academ…
1.什么是无锁(Lock-Free)编程 当谈及 Lock-Free 编程时,我们常将其概念与 Mutex(互斥) 或 Lock(锁) 联系在一起,描述要在编程中尽量少使用这些锁结构,降低线程间互相阻塞的机会,以提高应用程序的性能.类同的概念还有 "Lockless" 和 "Non-Blocking" 等.实际上,这样的描述只涵盖了 Lock-Free编程的一部分内容.本质上说,Lock-Free 编程仅描述了代码所表述的性质,而没有限定或要求代码该如何编写. 基本…
非阻塞同步算法与CAS(Compare and Swap)无锁算法 这篇问题对java的CAS讲的非常透彻! 锁的代价 1. 内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放.在上下文切换的时候,cpu之前缓存的指令和数据都将失效,对性能有很大的损失. 2. 用户态的锁虽然避免了这些问题,但是其实它们只是在没有真实的竞争时才有效. 乐观锁与悲观锁 1. 独占锁是一种悲观锁,synchronized就是一种独占锁,它假设…
基于无锁队列和c++11的高性能线程池线程使用c++11库和线程池之间的消息通讯使用一个简单的无锁消息队列适用于linux平台,gcc 4.6以上   标签: <无>   代码片段(6)[全屏查看所有代码] 1. [代码]lckfree.h ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 // lckfree.h…
Memory Barrier http://www.wowotech.net/kernel_synchronization/memory-barrier.html 这里面讲了Memory Barrier 对于一个c程序员,我们的编写的代码能所见即所得吗?我们看到的c程序的逻辑是否就是最后CPU运行的结果呢?很遗憾,不是,我们的"所见"和最后的执行结果隔着: 1.编译器 2.CPU取指执行 编译器了解底层CPU的思维模式,因此,它可以在将c翻译成汇编的时候进行优化(例如内存访问指令的重新…
在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论内存屏障的相关内容. 三.内存屏障 不知读者是是否记得在笔者讨论自旋锁的禁止或使能的时候,提到过一个内存屏障函数.OK,接下来,笔者将讨论内存屏障的具体细节内容.我们首先来看下它的概念,Memory Barrier是指编译器和处理器对代码进行优化(对读写指令进行重新排序)后,导致对内存的写入操作不能及时的反应到读操作中(锁机制无法保证时序正确).可能读起来…