首页 > 其他分享 >硬件结构 硬盘--

硬件结构 硬盘--

时间:2022-08-21 16:34:57浏览次数:51  
标签:缓存 -- 核心 Cache 硬件 内存 数据 CPU 硬盘

CPU 的高速缓存,通常可以分为 L1、L2、L3 这样的三层高速缓存,也称为一级缓存、二级缓存、三级缓存。

在 Linux 系统,我们可以通过这条命令,查看 CPU 里的 L1 Cache 「数据」缓存的容量大小:
$ cat /sys/devices/system/cpu/cpu0/cache/index0/size
32K

内存用的芯片和 CPU Cache 有所不同,它使用的是一种叫作 DRAM (Dynamic Random Access Memory,动态随机存取存储器) 的芯片。

相比 SRAM,DRAM 的密度更高,功耗更低,有更大的容量,而且造价比 SRAM 芯片便宜很多。

如何写出让 CPU 跑得更快的代码?
CPU 内部嵌入了 CPU Cache(高速缓存),它的存储容量很小,但是离 CPU 核心很近,所以缓存的读写速度是极快的,那么如果 CPU 运算时,直接从 CPU Cache 读取数据,而不是从内存的话,运算速度就会很快。

但是,大多数人不知道 CPU Cache 的运行机制,以至于不知道如何才能够写出能够配合 CPU Cache 工作机制的代码,一旦你掌握了它,你写代码的时候,就有新的优化思路了。

CPU Cache 是由很多个 Cache Line 组成的。
Cache Line 是由各种标志(Tag)+ 数据块(Data Block)

如何写出让 CPU 跑得更快的代码?

访问的数据在 CPU Cache 中的话,意味着缓存命中,缓存命中率越高的话,代码的性能就会越好,CPU 也就跑的越快。

经过测试,形式一 array[i][j] 执行时间比形式二 array[j][i] 快好几倍。

之所以有这么大的差距,是因为二维数组 array 所占用的内存是连续的,比如长度 N 的值是 2 的话,那么内存中的数组元素的布局顺序是这样的:

那访问 array[0][0] 元素时,CPU 具体会一次从内存中加载多少元素到 CPU Cache 呢?这个问题,在前面我们也提到过,这跟 CPU Cache Line 有关,它表示 CPU Cache 一次性能加载数据的大小,可以在 Linux 里通过 coherency_line_size 配置查看 它的大小,通常是 64 个字节。

分支预测器 先排序后遍历速度快

2.4 cpu缓存一致性
保持内存与 Cache 一致性最简单的方式是,把数据同时写入内存和 Cache 中,这种方法称为写直达(Write Through)。

在写回机制中,当发生写操作时,新的数据仅仅被写入 Cache Block 里,只有当修改过的 Cache Block「被替换」时才需要写到内存中,减少了数据写回内存的频率,这样便可以提高系统的性能。
修改过的cache才需要写回内存。

这时如果 A 号核心执行了 i++ 语句的时候,为了考虑性能,使用了我们前面所说的写回策略,先把值为 1 的执行结果写入到 L1/L2 Cache 中,然后把 L1/L2 Cache 中对应的 Block 标记为脏的,这个时候数据其实没有被同步到内存中的,因为写回策略,只有在 A 号核心中的这个 Cache Block 要被替换的时候,数据才会写入到内存里。
如果这时旁边的 B 号核心尝试从内存读取 i 变量的值,则读到的将会是错误的值,因为刚才 A 号核心更新 i 值还没写入到内存中,内存中的值还依然是 0。

修复!
第一点,某个 CPU 核心里的 Cache 数据更新时,必须要传播到其他核心的 Cache,这个称为写传播(Write Propagation); 传播到其他 cache

那么问题就来了,C 号核心先收到了 A 号核心更新数据的事件,再收到 B 号核心更新数据的事件,因此 C 号核心看到的变量 i 是先变成 100,后变成 200。

而如果 D 号核心收到的事件是反过来的,则 D 号核心看到的是变量 i 先变成 200,再变成 100,虽然是做到了写传播,但是各个 Cache 里面的数据还是不一致的。

所以,我们要保证 C 号核心和 D 号核心都能看到相同顺序的数据变化,比如变量 i 都是先变成 100,再变成 200,这样的过程就是事务的串行化。

为什么 0.1 + 0.2 不等于 0.3 ?

由于计算机的资源是有限的,所以是没办法用二进制精确的表示 0.1,只能用「近似值」来表示,就是在有限的精度情况下,最大化接近 0.1 的二进制数,于是就会造成精度缺失的情况。

标签:缓存,--,核心,Cache,硬件,内存,数据,CPU,硬盘
From: https://www.cnblogs.com/shenxiaodou/p/16610210.html

相关文章

  • 封面 - IT人之软件工具指南
     IT项目之软件项目工具指南   AGuidetoITSoftwareToolsIT人之软件工具指南--------------------------------------------------------------------------......
  • IDEA打包普通java项目并用java命令运行
    IDEA下打包为jar包,普通java项目(非web项目)效果是将第三方jar包放到一个文件夹中(如lib),这样看起来清晰一些。如下图这种:  1.项目结构。   1.关键:modules  ......
  • 视频播放
    //解析接口配置 //showType=1(仅PC),showType=2(仅mobile),showType=3(同时显示) constoriginalInterfaceList=[ {"name":"纯净/B站","url":"https://z1.m1907.cn/?j......
  • 瓶颈生成树
    瓶颈生成树定义无向图G,G的瓶颈生成树是一棵“树上最大边权值在G的所有生成树中最小”的生成树,这样的生成树可能不止一棵。瓶颈生成树的值为树上最大边权值。由瓶颈生......
  • 笔记本网卡总断连,如何使得网卡不自动休眠?
    笔记本网卡总断连,如何使得网卡不自动休眠?总结家里面的笔记本拿来开机做服务器,但是出门在外的时候没法远程连接回服务器,回到家发现是因为网卡休眠了。很抓狂。通过以下方......
  • Spring学习1-IOC、IOC容器、Bean、DI
    1.IOC(InversionofControl)控制反转   (1)什么是控制反转呢? 使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此......
  • 使用线程池,并发计算1~50、51~100的和,再进⾏汇总统计。
    知识点:获取线程池、提交任务、获取返回值 获取线程池的几种方式:newFixedThreadPool(intnThreads)获取固定数量的线程池。参数:指定线程池中线程的数量。(使用这种)newC......
  • crossover在mac安装KeyGen.exe注册机的方法
    Mac上一些应用的正常使用,如果想要运行windows的exe程序,可以借助crossover软件,今天为您带来crossover在mac安装KeyGen.exe注册机的方法。crossover在mac安装KeyGen.exe注册......
  • 关于Java 连接 MySQL 数据库报错:Failed to obtain JDBC Connection; ...: Communicati
    原因:是因为Java连接MySQL没有收到任何数据包,也就是说连接失败。解决方法:打开Windows服务程序,找到mysql进程,重启一下就可以了。......
  • redis-持久化
    https://blog.csdn.net/JavaTeachers/article/details/108998121https://www.pdai.tech/md/db/nosql-redis/db-redis-x-rdb-aof.html......