组相联cache如何快速实现cache line eviction并使用PMU events验证

如何快速实现cache line eviction

  • 一,什么是cache hit、miss、linefill、evict ?
    • 1.1 如果要程序员分别制造出cache hit、miss、linefill、evict这四种场景,该怎么做?
  • 二,实现cache line eviction的方法
    • 1.1 直接填充法
    • 3.2 针对组相联cache的固定set number 填充法
  • 三,使用PMU events验证 cache line eviction
  • 四,思考:全相联和直接映射型cache 如何实现 cache eviction ?

一,什么是cache hit、miss、linefill、evict ?

cache controler 是一个管理cache 内存的硬件结构,实际上它的绝大部分行为对程序来说都是不可见的。它会自动地将代码指令或者数据从主存中搬运到cache中,响应CPU读写内存的请求,并将它们转化成对cache以及外部内存的操作:
cache controler收到CPU对某个地址进行读写的请求时,它会先检查这个地址是否存在cache中,这个动作称为cache look-up(缓存查找)。具体的的操作为:将该地址的部分bit截取下来与cache 中cache line的tag(cache line的tag包含了该cache line的地址信息)值进行比较。如果匹配成功,也称为cache hit(命中),说明CPU读写的地址已存在cache中,并且这个cache line被标记为 valid(有效),则CPU的读写操作将会使用cache 里面的内容,而不会去主存中读写。
反之,如果遍历了整个cache都没有找到能与该地址匹配的tag,或者该tag是无效的,则缓存未命中(cache miss)。这个cache miss的结果以及对该地址的读写请求会被传递给下一级内存(可能是L2、L3 cache或者主存),并且会发生 cache linefill(缓存行填充)。cache linefill是指将下一级内存中关于该被请求地址的数据拷贝到cache中,由于cache 操作的最小单位是cache line,所以一次填充一个cache line。在cache linefill的同时,被请求的数据也会发送给CPU,满足其读写请求。这个cache miss 和linefill的行为对程序员来说是不可见的,并且CPU并不用等linefill完成,才能使用该数据。假设cache line大小为64 bytes,所以一个linefill操作需要将64 bytes数据拷贝到cache当中,而CPU的读写请求可能是该cache line中的其中一个word(4 bytes),cache controler会优先访问该特定的 word,将该word送到CPU的流水线(pipeline)中,与此同时,cache硬件以及外部总线接口会将剩余的60 bytes数据读取,并填充到指定cache line中。
cache 始终是有空间限制的,如果一直miss,一直linefill,那么将cache填满了后会发生什么?eviction。为了让新的cache line数据填进cache中,cache 利用替换策略(replacement policy),在cache中选中一个cache line,并将其驱逐(evict)出去,为新的cache line数据腾出空间。被驱逐的cache line也称为victim,而被驱逐的过程,也就是写回(write back)到下一级内存(可能是L2、L3 cache或者主存)的过程。
问题随之而来:

1.1 如果要程序员分别制造出cache hit、miss、linefill、evict这四种场景,该怎么做?

首先要知道cache miss之后必然会出现cache linefill,如果cache 满了,cache linefill还会造成cache eviction。所以:

  • cache miss +linefill : 读写一个之前未曾使用过的地址,或者当cache为空的时候进行读写,即可造成miss+linefill。
  • cache hit :重复读写一个内存地址,第一遍读写会miss+linefill,但是第二遍开始就会一直hit。
  • cache evict:前面提到过,当cache 满了的时候,会将某个cache line驱逐出去,给新的cache line腾出空间。所以最简单的办法就是连续读写一段与cache容量大小的内存空间,将cache 填满。然后再读写一个新的地址时,将会发生eviction。除了这种方法,下文还会介绍针对组相联结构的cache快速制造eviction的简单方法。

二,实现cache line eviction的方法

1.1 直接填充法

在上文中我们知道,要想发生 cache line的eviction,最简单粗暴的方式就是将整个cache 填满,然后再读写一个新地址的时候,cache controler就会用replacement policy(替换策略)选择其中一个cache line,将其驱逐(也就是write back)到下一级内存中。但是将一个cahce 填满也是非常耗时的,我们可以简单计算一下:
假设当前cache 的大小为32KB,其cache line size为64 bytes,LDR/STR指令一次读写32 bit( 4 bytes)的数据。我们知道,一次读写(miss)会填充一个cache line(64 bytes),即使是每次跨一个cache line大小的空间进行读写,实际的读写次数也需要512次,如下面代码:

addr = 0x10000000
for(i=0;i<512;i++)
{val=*(addr);addr = addr+64;
}
val=*(addr+64);//eviction

3.2 针对组相联cache的固定set number 填充法

ARM一般使用组相联结构的cache,针对组相联cache,不必将整个cache填满才会发生eviction,我们可以利用cache的set 和way快速地制造eviction,具体的原理如下参考下文。
假设有一个 4 way+ 256 set的cache,cache line大小为64 bytes,很容易得出该cache的大小为64 Bytes * 256 * 4 = 64 KB,其结构如下:
在这里插入图片描述
在这里插入图片描述
可以发现,传入cache的一个内存地址会被cache 分成三部分:Tag+Index+offset。这三部分决定了该地址上的数据将会被加载到cache中的哪个cache line。

  • Tag:一个地址的高位bits可以用来当作Tag,可以告诉cache该cache line的数据来自主存的哪里。
  • Index: 地址的中间部分可以用来表示 Set的下标,也就是set的行号,不同way中index相同的cache line的集合称为set。
  • Offset:word index + byte index,一个cache line有64 bytes,而一个地址上的数据可能只有4 bytes,我们可以用该offset找到该数据位于cache line的哪个word或者byte。

当CPU 读写一个地址后,假设该地址为0xB0001234,包含该地址数据的一个cache line大小的数据将会被填充到cache中。
我们先来分析该cache line将会被放在cache 的哪个位置。
0xB0001234会被分成三部分:
在这里插入图片描述
蓝色部分为Tag信息,红色部分为Set的index,绿色部分为offset:

  • Tag = 0b1011 0000 0000 0000 00
  • Set index = 0b 100100 = 0x24 = 36
  • offset: word index = 0b 1101 = 13, byte index = 0

解析出了这些信息,我们就可以给这个cache line找个家了:

  • 位于哪个way:由于是4 way组相联的cache,所以该cache line可以位于 way0、way1、way2、way3中的任意一个way。
  • 位于哪个Set:set index为36,所以该cache line位于某个way的第36行。
  • 位于cache line的第13个word的第 0 byte
    在这里插入图片描述
    需要注意的是,该地址不是64 bytes对齐的地址,所以加载到cache line的64 bytes数据应该是从 0xB0001200开始到 0xB0001240的 64 bytes数据。
    在这里插入图片描述

我们虽然不知道该cache line位于哪个way,但是way 的个数只有四个,如果连续写入四个 set index都为36的cache line,那么写入第五个的时候会发生什么?eviction

  1. 写入第一个set index为36 的cache line,cache line 可以保存在way0,way1,way2,way3,任意一个way,姑且假设放入way2。
  2. 写入第二个set index为36 的cache line,cache line 可以保存在way0,way1,way3,任意一个way,姑且假设放入way3。
  3. 以此类推,当写入第四个set index为36 的cache line后,way0,way1,way2,way3都保存了一个set index为36且来自不同地址的cache line。
  4. 如果再写入第五个set index为36 的cache line,cache controler将会根据替换策略,在现有的四个set index为36的cache line中选择一个,将其驱逐出去,为第五个set index为36 的cache line腾出空间,也就发生了cache eviction。
    在这里插入图片描述

所以接下来我们只要找到四个set index为36,但是Tag不同的地址即可,只要保证地址的[13:6]=0b0100 100,即可保证其set index为36 ,比如:

  • 0xA0001200
  • 0xC0001200
  • 0xD0001200
  • 0xE0001200
    在这里插入图片描述
    所以CPU只需先读写这四个地址,然后再读写0xB0001234的时候,将会发生cache eviction,总共只需读写五次即可实现。

三,使用PMU events验证 cache line eviction

光是这样推测是远远不够的,我们可以利用PMU(Performance Monitors Unit)的事件监控功能,把cache 相关的事件用PMU来监控,验证是否真的发生了预期的cache 操作。具体的event 可以是:
在这里插入图片描述
在这里插入图片描述
一个eviciton 操作实际上是将旧的cache line写回到下一级缓存,然后把新的cache line 加载进来,所以可以利用PMU以下的event来监控:

  • L1D_CACHE_WB
  • L2D_CACHE_REFILL
  • L2D_CACHE
  • L1D_CACHE
  • L1D_CACHE_REFILL

四,思考:全相联和直接映射型cache 如何实现 cache eviction ?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/66283.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android——基本控件(下)(二十)

1. 树型组件&#xff1a;ExpandableListView 1.1 知识点 &#xff08;1&#xff09;掌握树型组件的定义&#xff1b; &#xff08;2&#xff09;可以使用事件对树操作进行监听。 2. 具体内容 既然这个组件可以完成列表的功能&#xff0c;肯定就需要一个可以操作的数据&…

vue从零开始学习

npm install慢解决方法:删掉nodel_modules。 5.0.3:表示安装指定的5.0.3版本 ~5.0.3:表示安装5.0X中最新的版本 ^5.0.3: 表示安装5.x.x中最新的版本。 yarn的优点: 1.速度快,可以并行安装 2.安装版本统一 项目搭建: 安装nodejs查看node版本:node -v安装vue clie : np…

swaggo的一点小理解

如有错误&#xff0c;希望指出&#xff0c;谢谢&#xff01; 很低级的概念不清&#xff0c;大佬嘴下留情。 1.关于swag的注释 我的理解是这些注释是专门提供给Swagger UI界面测试使用的&#xff0c;根据注释内容告诉swag文档这个函数应该有哪些参数&#xff0c;从什么路由走&…

HarmonyOS/OpenHarmony(Stage模型)应用开发单一手势(二)

三、拖动手势&#xff08;PanGesture&#xff09; .PanGestureOptions(value?:{ fingers?:number; direction?:PanDirection; distance?:number}) 拖动手势用于触发拖动手势事件&#xff0c;滑动达到最小滑动距离&#xff08;默认值为5vp&#xff09;时拖动手势识别成功&am…

关于已经安装了TorchCRF,导入时却提示“ModuleNotFoundError: No module named ‘torchcrf‘”的解决办法

应用python时&#xff0c;想导入torchcrf库 from torchcrf import CRF 但系统提示&#xff1a;ModuleNotFoundError: No module named torchcrf 在命令提示符里输入“pip list”检查已安装库&#xff0c;发现torchcrf已经安装 搞了半天&#xff0c;发现是大小写的问题&#x…

Locked勒索病毒:最新变种.locked袭击了您的计算机?

导言&#xff1a; 在今天的数字时代&#xff0c;勒索病毒已经不再是仅仅让数据变得不可访问的小威胁。 .locked 勒索病毒&#xff0c;作为其中的一种&#xff0c;以其高度复杂的加密算法和迅速变化的攻击手法而备受恶意分子喜爱。本文91数据恢复将带您深入了解 .locked 勒索病毒…

C语言练习8(巩固提升)

C语言练习8 编程题 前言 奋斗是曲折的&#xff0c;“为有牺牲多壮志&#xff0c;敢教日月换新天”&#xff0c;要奋斗就会有牺牲&#xff0c;我们要始终发扬大无畏精神和无私奉献精神。奋斗者是精神最为富足的人&#xff0c;也是最懂得幸福、最享受幸福的人。正如马克思所讲&am…

Scala入门,idea关联Scala

Scala 介绍 Scala是一种多规范的编程语言&#xff0c;它结合了面向对象编程&#xff08;OOP&#xff09;和函数式编程&#xff08;FP&#xff09;的特征&#xff0c;Scala的名字源于”Scalable language“&#xff0c;意为”可伸缩语言“。2003年开发的&#xff0c;并在JVM&a…

如何设计一个好的游戏剧情(Part 1:主题的设定)

提醒&#xff1a;此教程仅仅为作者的一些经验和感悟&#xff0c;非专业教程&#xff0c;若介意请前往网上搜集或者书本查阅相关资料&#xff01; 前言&#xff1a;游戏为什么要有剧情——游戏剧情的重要性 游戏剧情的重要性难以低估。一个精彩的剧情可以让玩家感受到强烈的情感…

华为OD:敏感字段加密

题目描述&#xff1a; 给定一个由多个命令字组成的命令字符串&#xff1a; 1、字符串长度小于等于127字节,只包含大小写字母,数字,下划线和偶数个双引号&#xff1b; 2、命令字之间以一个或多个下划线_进行分割&#xff1b; 3、可以通过两个双引号”"来标识包含下划线…

抽象轻松c语言

目 c语言 c程序 c语言的核心在于语言&#xff0c;语言的作用是进行沟通&#xff0c;人与人之间的信息交换 人与人之间的信息交换是会有信息空白&#xff08;A表达信息&#xff0c;B接受信息&#xff0c;B对信息的处理会与A所以表达的信息具有差距&#xff0c;这段差距称为信…

keras深度学习框架通过简单神经网络实现手写数字识别

背景 keras深度学习框架&#xff0c;并不是一个独立的深度学习框架&#xff0c;它后台依赖tensorflow或者theano。大部分开发者应该使用的是tensorflow。keras可以很方便的像搭积木一样根据模型搭出我们需要的神经网络&#xff0c;然后进行编译&#xff0c;训练&#xff0c;测试…

用迅为i.MX6ULL开发板同一个网段概念

使用 nfs 之前&#xff0c;开发板、虚拟机 ubuntu、windows 电脑三者要互相 ping 通&#xff0c;这就涉及到了同一个网段 的概念。 概念&#xff1a;同一个网段是指 IP 地址和子网掩码相与得到的相同的网络地址。 快速判断同一个网段&#xff1a; &#xff08;1&#xff09…

JVM 是怎么设计来保证new对象的线程安全

1、采用 CAS 分配重试的方式来保证更新操作的原子性 2、每个线程在 Java 堆中预先分配一小块内存&#xff0c;也就是本地线程分配缓冲&#xff08;Thread Local AllocationBuffer&#xff0c;TLAB&#xff09;&#xff0c;要分配内存的线程&#xff0c;先在本地缓冲区中分配&a…

windows server 2019 安装sqlserver2012

在安装前&#xff0c;应先关闭系统防火墙 双击exe 选择【全新SQL Server独立安装或向现有安装添加功能】选项 运行完成后&#xff0c;如无失败或警告&#xff0c;点击确定&#xff0c;如果出现警告&#xff0c;需要处理掉再继续执行 点击下一步 勾选接受许可&#xff0c;点击下…

云原生Kubernetes:K8S概述

目录 一、理论 1.云原生 2.K8S 3.k8s集群架构与组件 二、总结 一、理论 1.云原生 &#xff08;1&#xff09;概念 云原生是一种基于容器、微服务和自动化运维的软件开发和部署方法。它可以使应用程序更加高效、可靠和可扩展&#xff0c;适用于各种不同的云平台。 如果…

【微服务部署】一、使用docker-compose部署Jenkins、SonarQube、PostgreSQL

一、安装 1、编写docker-compose部署Postgres、SonarQube、Jenkins的yml文件jenkins-compose.yml Postgres&#xff1a;作为SonarQube的数据库存储SonarQube&#xff1a;代码质量检查Jenkins&#xff1a;jenkins/jenkins:lts镜像&#xff0c;jenkinsci/blueocean镜像缺少node…

解决 filezilla 连接服务器失败问题

问题描述&#xff1a; 开始一直用的 XFTP 后来&#xff0c;它变成收费软件了&#xff0c;所以使用filezilla 代替 XFTP 之前用的还好好的&#xff0c;今天突然就报错了&#xff1a;按要求输入相关字段&#xff0c;连接 连接失败&#xff01;&#xff01;&#xff01;o(╥﹏╥…

使用 BERT 进行文本分类 (03/3)

一、说明 在使用BERT&#xff08;2&#xff09;进行文本分类时&#xff0c;我们讨论了什么是PyTorch以及如何预处理我们的数据&#xff0c;以便可以使用BERT模型对其进行分析。在这篇文章中&#xff0c;我将向您展示如何训练分类器并对其进行评估。 二、准备数据的又一个步骤 …

友元(个人学习笔记黑马学习)

1、全局函数做友元 #include <iostream> using namespace std; #include <string>//建筑物类 class Building {//goodGay全局函数是 Building好朋友 可以访问Building中私有成员friend void goodGay(Building* building);public:Building() {m_SittingRoom "…