写命中

写直达(Write Through)

信息会被同时写到cache的块和主存中。这样做虽然比较慢,但缺少代价小,不需要把整个块都写回主存。也不会发生一致性问题。

对于写直达,多出来%10向主存写入的存储指令使得其比其单纯向Cache写入的速度慢上将近10倍。这种速度不一致的问题,不管是在硬件结构还是软件,有着一条“不管怎么样,先试试这样行不行”的办法:并行加缓冲。

我们使用写缓冲(Write Buffer)来解决这个问题,CPU写入Cache的同时会写入Write Buffer。缓冲中的内容什么时候写入主存交给存控(Memory Controller)来控制,CPU将省下的时间去处理其他事情。

Write Buffer是一个FIFO队列,一般只有4字节。

然而当写操作频繁的时候,这点容量就不够用了,容易饱和发生阻塞,就相当于没加一样...

解决的办法可以是再加一级Cache,变成二级缓存。什么,你问为什么不把两级Cache和一起,搞那么多干什么?这个二级当然是慢一点的便宜货,咱们弄这些东西,不就是因为越快东西越贵,买不起嘛土豪!

对于缓冲的问题,还有个关于合并写对程序效率的影响, 具体可以参考这篇博文

第二种办法就是改变策略使用写回,也就是下面介绍的方法。

写回(Write Back)

信息仅仅写到Cache中的块。当其被替换时,信息才会被写回到主存中。虚拟存储器系统通常采用写回策略,因为写到磁盘的延迟代价太大。

写回的速度要更快一些,因为不必每次写操作都访问主存。但这样我们如何保证一致性问题呢?我们可以给每行添加一个脏位(dirty bit),这样我们替换这块Cache时就可以根据脏位来判断是否需要写回主存。如果没有被“弄脏过”,那么就不需要写回主存。

不过对于同一块Cache中的变量X,他不是太喜欢这个机制。因为它的邻居Y老是被修改,导致X这个只被读取的变量老得往内存跑,它不想跟Y待在一起了,太累人了。

聆听了X的心声,我们有什么办法可以帮助它吗?办法当然是有的,让Y这个烦人的家伙单独待着就行。下面分别运行两个程序,排除首次装入的影响(其实写一块也行,对齐的技巧源自Disruptor)

public class Padding {

    private static class X {
public long p1,p2,p3,p4,p5,p6,p7;//cache padding
public volatile long x=0L;
public long p9,p10,p11,p12,p13,p14,p15;
//8*8刚好占满Cache一行,p9...p15只是为了确保x单独在一行中,不与其他频繁修改的变量在一起
}
public static X[] arrX=new X[2];
static {
arrX[0]=new X();
arrX[1]=new X();
}
public static void main(String[] args) throws InterruptedException {
Thread thread1=new Thread(()->{
for(long i=0;i<100_000_000L;i++)
arrX[0].x=i;
}); Thread thread2=new Thread(()->{
for(long i=0;i<100_000_000L;i++)
arrX[0].x=i;
});
final long start=System.nanoTime();
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println((System.nanoTime()-start)/1_000_000);
}
}
package mytask;

public class NoPadding {
private static class X {
public volatile long x=0L;
} public static X[] arrX=new X[2];
static {
arrX[0]=new X();
arrX[1]=new X();
} public static void main(String[] args) throws InterruptedException {
Thread thread1=new Thread(()->{
for(long i=0;i<100_000_000L;i++)
arrX[0].x=i;
}); Thread thread2=new Thread(()->{
for(long i=0;i<100_000_000L;i++)
arrX[0].x=i;
});
final long start=System.nanoTime();
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println((System.nanoTime()-start)/1_000_000);
}
}

写不命中

对于写不命中,有两者方法:写分配与非写分配。前者利用空间局部性,每次都从主存中读取一个块装入Cache更新相应单元。后者则是直接写主存单元,不将主存块装入Cache。

Cache写策略(Cache一致性问题与骚操作)的更多相关文章

  1. cache写策略

    cache写策略 Write Through (完全写入) CPU向cache写入数据时,同时向memory也写一份,使cache和memory的数据保持一致.优点是简单,缺点是每次都要访问memor ...

  2. 转:深入浅出cache写策略

    转自:http://www.ssdfans.com www.ssdfans.com › blog › 2018/07/27 › 深入浅出cach... 随着计算机行业的飞速发展,CPU的速度和内存的大 ...

  3. [转帖]CPU Cache 机制以及 Cache miss

    CPU Cache 机制以及 Cache miss https://www.cnblogs.com/jokerjason/p/10711022.html CPU体系结构之cache小结 1.What ...

  4. CPU Cache 机制以及 Cache miss

    CPU体系结构之cache小结 1.What is cache? Cache是用来对内存数据的缓存. CPU要访问的数据在Cache中有缓存,称为“命中” (Hit),反之则称为“缺失” (Miss) ...

  5. CPU中的cache结构以及cache一致性

    一. 引子 在多线程环境中,经常会有一些计数操作,用来统计线上服务的一些qps.平均延时.error等.为了完成这些统计,可以实现一个多线程环境下的计数器类库,方便记录和查看用户程序中的各类数值.在实 ...

  6. 缓存读写策略 - Cache Aside.md

    场景描述 比如一条数据同时存在数据库.缓存,现在你要更新此数据,你会怎么更新? 先更新数据库?还是先更新缓存? 其实这两种方式都有问题. (1)先更新数据库,后更新缓存 这样会造成数据不一致. A 先 ...

  7. Cache写机制

    Cache 写机制分为:Write-through和Write-back Write-through(直写模式) 定义:在数据更新时,同时写入缓存Cache和后端存储(主存): 优点:操作简单: 缺点 ...

  8. Mybatis Cache 缓存策略

    Mybatis Cache 缓存策略 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用 ...

  9. 阵列卡raid H730写策略write-through和write-back配置说明

    问题描述: 最近公司新进了测试服务器,但是在做阵列的时候忘记写策略里面的配置意思了 就网上查了一下,然后顺便做个笔记记录一下 write-through 数据在写入存储的同时,要写入缓存,这种方式安全 ...

随机推荐

  1. Java实现 蓝桥杯VIP 算法提高 传染病控制

    算法提高 传染病控制 时间限制:1.0s 内存限制:512.0MB 问题描述 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的 ...

  2. Java实现 洛谷 P1149 火柴棒等式

    import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.S ...

  3. java实现 蓝桥杯 算法训练 操作格子

    问题描述 有n个格子,从左到右放成一排,编号为1-n. 共有m次操作,有3种操作类型: 1.修改一个格子的权值, 2.求连续一段格子权值和, 3.求连续一段格子的最大值. 对于每个2.3操作输出你所求 ...

  4. java实现生日相同概率

    假设所有年份都只有365天,求n个人中,出现生日相同的概率. 输入n 输出相同的概率(保留3位有效数字即可) import java.util.*; public class X { // n个人出现 ...

  5. 【CSS】常用色值

    常用颜色: 嫣红(red):#e54d42 桔橙(orange):#f37b1d 明黄(yellow):#fbbd08 橄榄(olive):#8dc63f 森绿(green):#39b54a 天青(c ...

  6. linux下使用tcpdump抓包分析tcp的三次握手

    首先贴上tcp 三次握手的原理图服务器开启ftp服务并执行tcpdump抓包服务器:192.168.3.14 ftp服务客户端:192.168.3.100 服务器执行以下命令,客户端访问服务器ftp: ...

  7. python—面向对象设计

    一:三大编程范式 1.面向过程编程 2.函数式编程 3.面向对象编程 (类:把一类事物的相同的特征和动作整合到一起就是类,类是一个抽象的概念) (对象:就是基于类而创建的一个具体的事物 [具体存在的] ...

  8. EasyARM-iMX257 linux两年前的笔记

    我依然清晰的记得刚拿到Imx283 257的情景,兴奋中充满忧虑,对操作系统的概念只知一二,不知三四!!周立功出品的资料我一直觉得是比较精品的,同样这款iMX283配套的文档资料(v1.04)也是比较 ...

  9. Jmeter(八) - 从入门到精通 - JMeter配置元件(详解教程)

    1.简介 JMeter配置元件可以用来初始化默认值和变量,读取文件数据,设置公共请求参数,赋予变量值等,以便后续采样器使用.将在其作用域的初始化阶段处理.配置元件(Config Element)提供对 ...

  10. MyBatis运行流程及入门第一个程序

    1. mybatis是什么? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并 ...