cpu缓存

链表的应用(LRU缓存淘汰算法)

江枫思渺然 提交于 2020-02-29 20:41:18
缓存:是一种提高数据读取性能的技术,在硬件设计、软件开发中都有着非常广泛的应用,比如常见的 CPU 缓存、数据库缓存、浏览器缓存等等。 LRU:缓存的大小有限,当缓存被用满时数据有的需要删除,有的需要保留,这里我们采用的策略是LRU(最近最少使用)缓存淘汰算法。 LRU缓存淘汰算法:我们维护一个有序单链表,越靠近链表尾部的结点是越早之前访问的。当有一个新的数据被访问时,我们从链表头开始顺序遍历链表。 1. 如果此数据之前已经被缓存在链表中了,我们遍历得到这个数据对应的结点,并将其从原来的位置删除,然后再插入到链表的头部。 2. 如果此数据没有在缓存链表中,又可以分为两种情况: 如果此时缓存未满,则将此结点直接插入到链表的头部; 如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部。 来源: CSDN 作者: UCSD☁️ 链接: https://blog.csdn.net/qq_43536300/article/details/104573084

01.计算机体系结构概述.md

自作多情 提交于 2020-02-28 22:12:45
文章目录 1. 计算机的基本构成 1.1 cpu概览 2. 指令的执行过程 2.1 指令周期 2.2 指令分类 2.3 指令的格式 2.4 参考其他周期 3. 中断 3.1 中断的分类 3.2 中断和指令周期 3.3 中断响应的一般过程 3.4 多个中断 4. 缓存 5. 直接内存存取DMA技术 6. 计算机的并行处理手段 6.1. 对称多处理器SMP: 6.1.1 SMP的架构 6.1.2 SMP的优点 6.1.3 SMP各自拥有独立的缓存导致的数据一致性问题: 6.2. 多核计算机 6.2.1 多核和smp之间的区别 1. 计算机的基本构成 处理器:控制计算机操作,执行数据处理等功能。 内存:存储数据和程序,是易丢失的。 输入/输出模块(I/O): 在计算机和外部环境之间移动数据。外部环境有各种外部辅助设备,比如硬盘,显示器,鼠标。 系统总线:在处理器,内存,输入输出设备之间提供通信的设施。 1.1 cpu概览 cpu处理器的 一种 功能是和存储器交换数据,因此他通常使用两个内部寄存器: 1.存储器地址寄存器(Memory Address Register):用于确定下一次读写的存储器地址。 2.存储器缓冲寄存器(Memory Buffer Register): 存放从存储器读进来的数据或者是要写入到寄存器中的数据。 同样,还有一组寄存器用来和输入和输出设备 1

什么技能产品经理不会提,但技术人必须懂?

断了今生、忘了曾经 提交于 2020-02-28 05:09:18
缓存是搭建高性能高并发系统的必备手段之一,通常用来解决性能瓶颈,是程序员的必备知识点,也是面试必备考点。 尽管,产品经理大概率不会关注系统性能,但程序员在实现需求的时候必须思考系统承载的并发量和用户量。缓存主要用来解决性能瓶颈的问题,一旦错误使用反而会令系统崩溃。今天,我们就通过4W的方式系统化地总结缓存相关的理论知识。 随着互联网业务的快速迭代以及用户量激增,应用架构需要不断调整甚至重构以适应这种业务的快速发展。当数据量迅速增长,业务逻辑越复杂,服务链路不断增加等等一系列问题,会导致RT过长,服务性能需要逐渐提升以满足更优的用户体验。在优化系统架构时通常的所用的两种方式scale up以及scale out,scale out就是通常所说的水平扩展,将应用服务设计成无状态性,可以方便水平扩展通过增加硬件的方式分解访问压力。而scale up则是将单个服务链路性能提升,以提升QPS以及系统的吞吐量。在追求更优的性能时,大多数业务场景是读多写少的情况,一般会通过引入缓存的方式解决。 What——什么是缓存? 关于缓存的定义,在wiki中为: a collection of data duplicating original values stored elsewhere on a computer, usually for easier access.

🔥史上最全的Java并发系列之Java并发机制的底层实现原理

社会主义新天地 提交于 2020-02-26 05:10:55
并发编程的3个基本概念 原子性 定义: 即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。 原子性是拒绝多线程操作的,不论是多核还是单核,具有原子性的量,同一时刻只能有一个线程来对它进行操作。简而言之,在整个操作过程中不会被线程调度器中断的操作,都可认为是原子性。例如 a=1是原子性操作,但是a++和a +=1就不是原子性操作。Java中的原子性操作包括: a. 基本类型的读取和赋值操作,且赋值必须是数字赋值给变量,变量之间的相互赋值不是原子性操作。 b.所有引用reference的赋值操作 c.java.concurrent.Atomic.* 包中所有类的一切操作 可见性 定义:指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。 在多线程环境下,一个线程对共享变量的操作对其他线程是不可见的。Java提供了volatile来保证可见性,当一个变量被volatile修饰后,表示着线程本地内存无效,当一个线程修改共享变量后他会立即被更新到主内存中,其他线程读取共享变量时,会直接从主内存中读取。当然,synchronize和Lock都可以保证可见性。synchronized和Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存当中。因此可以保证可见性。 有序性 定义

volitale 关键字

余生长醉 提交于 2020-02-21 04:16:41
一、前言 volitale 知识点主要涉及JAVA内存模型的知识点,volitale提供了内存可见性和禁止指令重排的功能。 参考文章: https://blog.csdn.net/eff666/article/details/67640648 二、知识点 1.内存可见性 对变量进行访问和赋值时,观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令。lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能: (1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成; (2)它会强制将对缓存的修改操作立即写入主内存; (3)如果是写操作,它会导致其他CPU中对应的缓存行无效。 处理器为了提高处理速度,不直接和内存进行通讯,而是将系统内存的数据独到内部缓存后再进行操作,但操作完后不知什么时候会写到内存。 如果对声明了volatile变量进行写操作时,JVM会向处理器发送一条Lock前缀的指令,将这个变量所在缓存行的数据写会到系统内存。这一步确保了如果有其他线程对声明了volatile变量进行修改,则立即更新主内存中数据。 但这时候其他处理器的缓存还是旧的

并发编程之无锁

大憨熊 提交于 2020-02-16 21:03:53
并发编程之无锁 6.2 CAS与volatile 源码之LongAdder 6.8 Unsafe 6.2 CAS与volatile 其中的关键是compareAndSet,它的简称就是CAS(也有Compare And Swap的说法),它必须是原子操作。 注意 其实CAS的底层是lock cmpxchg指令(X86架构),在单核CPU和多核CPU下都能够保证【比较-交换】的原子性。 在多核状态下,某个核执行到带lock的指令时,CPU会让总线锁住,当这个核把此指令执行完毕,再开启总线。这个过程中不会被线程的调度机制所打断,保证了多个线程对内存操作的准确性,是原子的。 volatile 获取共享变量时,为了保证变量的可见性,需要使用volatile修饰。 它可以用来修饰成员变量和静态成员变量,他可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作volatile变量都是直接操作主存。即一个线程对volatile变量的修改,对另一个线程可见。 注意 : volatile仅仅保证了共享变量的可见性,让其它线程能够看到最新值,但不能解决指令交错问题(不能保证原子性) CAS必须借助volatile才能读取到共享变量的最新值来实现【比较并交换】的效果 为什么无锁效率高 无锁情况下,即使重试失败,线程始终在高速运行,没有停歇

缓存有那么多种,分别是干什么的?

一笑奈何 提交于 2020-02-13 00:59:20
(转载自 https://www.ithome.com/0/433/406.htm ) 只要是位正儿八经的程序员应该都知道“缓存”是什么,甚至我司的很多做运营的小姐姐现在和程序员小哥哥交流中都时不时冒出“缓存”这个词,让人压力山大。 当然,这里讨论的是指软件层面的缓存。大家都知道的一点是,缓存可以让原本打开很慢的页面,变得能“秒开”。你平时访问的App与网站几乎都有涉及到缓存的运用。 那么,缓存除了能加速数据的访问之外,还有什么作用呢? 另外,任何事物都有两面性,我们如何才能将缓存的优点发挥得淋漓尽致,同时避免掉到它的弊端中呢? 本文接下来就给大家分享一下如何理解缓存,以及它的运用思路,希望对你有所启发。 缓存能做什么? 正如前面所说,大家最普遍的理解就是当我们遇到某个页面打开很慢的时候,会想到引入缓存,这样页面打开就快了。 其实快和慢都是相对的,从技术角度来说,缓存之所以快是因为缓存是基于内存去建立的,而内存的读写速度比硬盘快X倍,所以用内存来代替硬盘作为读写的介质自然能大大提高访问数据的速度。 这个过程大致是这样的, 通过在内存中存储被访问过的数据供后续访问时使用,以此来达到提速的效果。 其实除此之外,缓存还有另外2个重要的运用方式: 预读取和延迟写 。 预读取 预读取就是预先读取将要载入的数据,也可以称作“缓存预热”,它是 在系统中先将硬盘中的一部分数据加载到内存中

浅谈缓存系统的三个问题

这一生的挚爱 提交于 2020-02-11 11:11:21
缓存雪崩 Cache Avalanche 缓存穿透 Cache Penetration 缓存击穿 Hotspot Invalid 浅谈缓存系统的三个问题 一.无处不在的缓存 缓存在计算机系统是无处不在,在CPU层面有L1-L3的Cache,在Linux中有TLB加速虚拟地址和物理地址的转换,在应用层有Redis等内存数据库缓存、在浏览器有本地缓存、手机有本地文件缓存等等。 可见,缓存在计算机系统中有非常重要的地位,主要作用就是提高响应速度、减少磁盘读取等,本文主要讨论在高并发系统中的缓存系统。一句话概括缓存系统在高并发系统中的地位的话,就是: 如果高并发系统是烤羊肉串,那么缓存系统就是那一撮孜然...... 二.高并发系统中的缓存 缓存系统的作用 缓存系统在高并发系统的作用巨大,没有缓存系统很难支撑C50K(或许这个值已经非常乐观了)以上的场景。 基于机械磁盘或SSD的数据库系统,读写的速度远慢于内存,因此单纯磁盘介质的数据库无法支撑高并发,你可以认为缓存就是为了保护磁盘数据库、是磁盘数据库的屏障。 缓存系统和数据库系统的访问 以读多写少的场景为例(实际场景也是读多写少),看看请求是如何得到响应的,简单流程:请求到达之后,业务线程首先访问缓存,如果缓存命中则返回,如果未命中则继续请求磁盘数据库系统,并将结果回写到缓存系统且增加老化时间

jvm 内存模型

荒凉一梦 提交于 2020-02-09 04:12:53
cpu和计算机内存的交互 在计算机中,cpu和内存的交互最为频繁,相比内存,磁盘读写太慢,内存相当于高速的缓冲区 但是随着cpu的发展,内存的读写速度也远远赶不上cpu。因此cpu厂商在每颗cpu上加上高速缓存,用于缓解这种情况。现在cpu和内存的交互大致如下。 cpu上加入了高速缓存这样做解决了处理器和内存的矛盾(一快一慢),但是引来的新的问题是缓存一致性 缓存一致性 在多核cpu中,每个处理器都有各自的高速缓存(L1,L2,L3),而主内存确只有一个 。 CPU要读取一个数据时,首先从一级缓存中查找,如果没有找到再从二级缓存中查找,如果还是没有就从三级缓存或内存中查找,每个cpu有且只有一套自己的缓存。 如何保证多个处理器运算涉及到同一个内存区域时,多线程场景下会存在缓存一致性问题,那么运行时保证数据一致性? 为了解决这个问题,各个处理器需遵循一些协议保证一致性。【如MSI,MESI啥啥的协议。。】 在CPU层面,内存屏障提供了个充分必要条件 内存屏障(Memory Barrier) 什么时内存屏障 CPU中,每个CPU又有多级缓存【上图统一定义为高速缓存】,一般分为L1,L2,L3,因为这些缓存的出现,提高了数据访问性能,避免每次都向内存索取,但是弊端也很明显,不能实时的和内存发生信息交换,分 在不同CPU执行的不同线程对同一个变量的缓存值不同。 硬件层的内存屏障分为两种:

锁(Lock)、内存屏障(Memory barrier)与 缓存一致性( Cache coherence)

假如想象 提交于 2020-02-08 05:08:53
在应用层,关于锁的使用大家应该都很熟悉了,作用就是为了保护共享变量不被同时操作而导致无法预测的情况。然而深入到具体实现,锁仅仅只是锁定临界区吗? 锁的实现其实还必须实现一个语义,也就是内存屏障。内存屏障主要用于防止指令重排而导致的无法预测的情况。代码经过编译器生成的指令并不一定都是按着我们原先的想法来生成的,可能经过优化等情况进行了指令的重排,然而这些重排在执行后的结果应当是一致的。其实及时编译器不重排指令,在现代的cpu中,也常常会将指令乱序执行,所以内存屏障可以保证屏障指令前后的指令顺序。 Memory barrier Memory barrier 也称为 membar,存储器围栏或栅栏指令,是一种类型的屏障指令,其使得一个中央处理单元(CPU)或 编译器执行的排序上约束存储器之前和屏障指令后发出的操作。 这通常意味着可以保证在屏障之前发布的操作可以在屏障之后发布的操作之前执行 。 内存屏障是必需的,因为大多数现代CPU都采用了性能优化,这些性能优化可能导致乱序执行。通常在单个执行线程中不会注意到这种内存操作(装入和存储)的重新排序,但是除非仔细控制,否则可能在并发程序和设备驱动程序中导致不可预测的行为。排序约束的确切性质取决于硬件,并由体系结构的内存排序模型定义。一些体系结构为实施不同的排序约束提供了多个障碍。 当实现在多个设备共享的内存上运行的低级机器代码时