首页 > 其他分享 >单生产者单消费者无锁队列

单生产者单消费者无锁队列

时间:2024-09-09 18:25:21浏览次数:1  
标签:无锁 队列 Cache 生产者 缓存 线程 L3 共享 CPU

单生产者单消费者无锁队列

伪共享:

下图是计算的基本结构。L1、L2、L3分别表示一级缓存、二级缓存、三级缓存,越靠近CPU的缓存,速度越快,容量也越小。所以L1缓存很小但很快,并且紧靠着在使用它的CPU内核;L2大一些,也慢一些,并且仍然只能被一个单独的CPU核使用;L3更大、更慢,并且被单个插槽上的所有CPU核共享;最后是主存,由全部插槽上的所有CPU核共享。

级别越小的缓存,越接近CPU, 意味着速度越快且容量越少。

  • L1是最接近CPU的,它容量最小,速度最快,每个核上都有一个L1 Cache(准确地说每个核上有两个L1 Cache, 一个存数据 L1d Cache, 一个存指令 L1i Cache);
  • L2 Cache 更大一些,例如256K,速度要慢一些,一般情况下每个核上都有一个独立的L2 Cache;二级缓存就是一级缓存的缓冲器:一级缓存制造成本很高因此它的容量有限,二级缓存的作用就是存储那些CPU处理时需要用到、一级缓存又无法存储的数据。
  • L3 Cache是三级缓存中最大的一级,例如12MB,同时也是最慢的一级,在同一个CPU插槽之间的核共享一个L3 Cache。三级缓存和内存可以看作是二级缓存的缓冲器,它们的容量递增,但单位制造成本却递减。

L3 Cache是三级缓存中最大的一级,例如12MB,同时也是最慢的一级,在同一个CPU插槽之间的核共享一个L3 Cache。三级缓存和内存可以看作是二级缓存的缓冲器,它们的容量递增,但单位制造成本却递减。

缓存行 cache line

缓存,是由缓存行Cache Line组成的。一般一行缓存行有64字节。所以使用缓存时,并不是一个一个字节使用,而是一行缓存行、一行缓存行这样使用;换句话说,CPU存取缓存都是按照一行,为最小单位操作的。

Cache Line可以简单的理解为CPU Cache中的最小缓存单位。目前主流的CPU Cache的Cache Line大小都是64Bytes。假设我们有一个512字节的一级缓存,那么按照64B的缓存单位大小来算,这个一级缓存所能存放的缓存个数就是512/64 = 8个。

伪共享问题

CPU的缓存系统是以缓存行(cache line)为单位存储的,一般的大小为64bytes。在多线程程序的执行过程中,存在着一种情况,多个需要频繁修改的变量存在同一个缓存行当中。
假设:有两个线程分别访问并修改X和Y这两个变量,X和Y恰好在同一个缓存行上,这两个线程分别在不同的CPU上执行。那么每个CPU分别更新好X和Y时将缓存行刷入内存时,发现有别的修改了各自缓存行内的数据,这时缓存行会失效,从L3中重新获取。这样的话,程序执行效率明显下降。为了减少这种情况的发生,其实就是避免X和Y在同一个缓存行中,可以主动添加一些无关变量将缓存行填充满,比如在X对象中添加一些变量,让它有64 Byte那么大,正好占满一个缓存行。

两个线程(Thread1 和 Thread2)同时修改一个同一个缓存行上的数据 X Y:

如果线程1打算更改a的值,而线程2准备更改b的值:

Thread1:x=3;

Thread2:y=2;

由x值被更新了,所以x值需要在线程1和线程2之间传递(从线程1到线程2),x的变更会引起整块64bytes被交换,因为cpu核之间以cache lines的形式交换数据(cache lines的大小一般为64bytes)。
每个线程在不同的核中被处理。x,y是两个频繁修改的变量,x,y,还位于同一个缓存行.
如果,CPU1修改了变量x时,L3中的缓存行数据就失效了,也就是CPU2中的缓存行数据也失效了,CPU2需要的y需要重新从内存加载。
如果,CPU2修改了变量y时,L3中的缓存行数据就失效了,也就是CPU1中的缓存行数据也失效了,CPU1需要的x需要重新从内存加载。
x,y在两个cpu上进行修改,本来应该是互不影响的,但是由于缓存行在一起,导致了相互受到了影响。

对缓存行中的单个变量进行修改了,导致整个缓存行数据也就失效了,并且,会导致其他CPU的含有被改动的共享变量的缓存行也失效了,就是所谓的伪共享问题。

而缓存行是为了解决缓存一致性的问题,所引入的。所以,解决缓存一致性的问题,又导致了伪共享问题的出现。

block


队列被组织为一个一个的缓冲块所构成的循环单链表:

  • 每个块里都有一个缓冲区data,用于构造T对象.
  • front, tail表示data中存放数据的其实位置和末尾位置,相当于data就是一个数组构成小型队列。都为原子类型。
  • 在实现中,块的内存向cache line对齐,大小为64,由于多个线程会频繁的访问fronttail,因此需要将它们分别放到不同的cache line为了防止伪共享问题。

标签:无锁,队列,Cache,生产者,缓存,线程,L3,共享,CPU
From: https://www.cnblogs.com/sfbslover/p/18405022

相关文章

  • 洛谷题单指南-常见优化技巧-P1886 滑动窗口 /【模板】单调队列
    原题链接:https://www.luogu.com.cn/problem/P1886题意解读:单调队列模版题。解题思路:采用双端队列维护单调的序列,单调队列三部曲:1、去头,当窗口内元素个数超过k,队头出队2、去尾,当要加入的元素会破坏单调性,队尾出队3、入队,将元素的下标存入队列每一次入队后,队头元素即为窗口最......
  • 多线程篇(阻塞队列- DelayQueue)(持续更新迭代)
    目录一、简介二、基本原理四、代码示例简单定时调度任务多消费者定时调度任务得出结论四、应用场景一、简介DelayQueue是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。这种队列是有序的,即队头对象的延迟到......
  • 多线程篇(阻塞队列- PriorityBlockingQueue)(持续更新迭代)
    目录一、简介二、类图三、源码解析1.字段讲解2.构造方法3.入队方法put浮调整比较器方法的实现入队图解4.出队方法takedequeue下沉调整比较器方法的实现出队图解四、总结一、简介PriorityBlockingQueue队列是JDK1.5的时候出来的一个阻塞队列。但是该队......
  • 【算法笔记】单源最短路问题——Dijkstra算法(无优化/优先队列/set优化)
    0.前言Dijkstra算法可在\(\mathcalO(m\logm)\)或\(\mathcalO(m\logn)\)的时间内求解无负权单源最短路问题。本文中,我们将详细介绍算法的原理、实现,以及常用的两种优化。另外,Dijkstra算法也不要乱用,比如说多源的最短路,用Dijkstra求解的复杂度只有\(\mathcalO(nm\logm)\),但......
  • Redis 实现延迟队列的巧妙方法
    今天我们来探索一下Redis是如何巧妙地实现延迟队列的,这可是在很多场景下都非常实用的技术哦!一、什么是延迟队列?延迟队列,简单来说,就是可以让消息在指定的延迟时间之后才被消费的队列。想象一下,你在网上订了一份外卖,商家并不会立即配送,而是根据你选择的送达时间,延迟一段时......
  • 【数据结构】栈与队列OJ题(用队列实现栈)(用栈实现队列)
    目录1.用队列实现栈oj题对比一、初始化二、出栈 三、入栈四、取队头元素:2.用栈实现队列 一、定义二、入队列三、出队列四、队头五、判空                                      ......
  • DAY11 栈与队列part02
      逆波兰式求值代码随想录(programmercarl.com)1classSolution{2public:3intevalRPN(vector<string>&tokens){4stack<longlong>st;5for(inti=0;i<tokens.size();i++)6{78if(tokens[i]=="+......
  • FreeRTOS 队列 Queue 源码解析
    目录一、队列1、队列结构体2、队列类型二、队列相关操作1、初始化1.1静态创建队列1.2动态创建队列1.3队列的初始化1.4队列的重置2、队列的发送2.1任务级入队函数2.1.1入队函数2.1.2队列锁2.1.3portYIELD_WITHIN_API2.2中断级入队函数3、任务的读取3.1任务......
  • 【代码随想录Day10】栈与队列Part01
    232.用栈实现队列题目链接/文章讲解/视频讲解:用栈实现队列classMyQueue{Stack<Integer>stackIn;Stack<Integer>stackOut;publicMyQueue(){stackIn=newStack<>();stackOut=newStack<>();}publicvoidpush(int......
  • 【洛谷 P1996】约瑟夫问题 题解(队列+模拟+循环)
    约瑟夫问题题目描述个人围成一圈,从第一个人开始报数,数到的人出列,再由下一个人重新从开始报数,数到的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰名小朋友,而该题是全部出圈。输入......