当前位置: 首页 > news >正文

直接映射例题及解析

目录

基本单位换算

 例题一

📁 Tag Directory(标签目录) 是什么?

例题二

例题三 

例题四

串行访问还是并行访问的选择 

例题五 

 例题六

例题七 

🔵 P1:(按行访问)

🔴 P2:(按列访问)

为什么一定会有miss? 

为什么按行访问和按列访问的 Miss 不一样?

 例题八

地址冲突


在正式解题之前,我们要先理解相关单位和基本概念,建立一个坚实的知识基础。

基本单位换算

这里我们要分清楚两个“进制体系”:

  • 十进制单位(以1000为基准,常用于网络带宽等)

  • 二进制单位(以1024为基准,常用于内存、缓存容量)

1. 十进制(以1000为基数)

中文英文前缀换算关系表示意义
Kilo1 K = 1000 = 10³一千个单位
Mega1 M = 1000 K = 10⁶一百万个单位
Giga1 G = 1000 M = 10⁹十亿个单位

这种用法常见于:网络带宽(Mbps)、硬盘厂商标注容量等场景
比如:

  • 1 Gbps = 1,000,000,000 bits(十亿位)

2. 二进制(以1024为基数)👉 更常用于内存、缓存

中文英文缩写换算关系二进制指数表示
千字节KB1 KB = 1024 Bytes2¹⁰ Bytes
兆字节MB1 MB = 1024 KB = 2²⁰ B
吉字节GB1 GB = 1024 MB = 2³⁰ B

这种定义广泛用于计算机系统、操作系统、编译器、主存/缓存等
比如:

  • 1 MB = 1,048,576 Bytes (而不是 1,000,000)

位(bit)和字节(Byte)

单位英文大小关系注释
bit最小单位可取 0 或 1
字节Byte1 Byte = 8 bits一个 ASCII 字符通常是 1 Byte

📏 容量单位(Capacity Units)

单位(中文)单位(英文)十进制定义二进制定义
千字节Kilobyte (KB)1 KB = 1000 Bytes1 KB = 2¹⁰ = 1024 Bytes
兆字节Megabyte (MB)1 MB = 1000 KB1 MB = 2²⁰ = 1,048,576 Bytes
吉字节Gigabyte (GB)1 GB = 1000 MB1 GB = 2³⁰ = 1,073,741,824 Bytes
字节Byte (B)1 Byte = 8 bits-
Bit (bit)最小的信息单位-

 例题一

📘 1. 物理地址(PA, Physical Address)

物理地址是CPU发出访问内存的真实地址。以**位数(bits)**表示其寻址范围:

  • 若物理地址有 n 位,则最大可寻址空间为 2ⁿ Bytes。

📘 2. 主存大小(MM Size)

题目给出 MM Size = 4GB,也就是:

4 GB = 4 × 2³⁰ B = 2² × 2³⁰ = 2³² Bytes
=> 所以物理地址长度 PA = 32 bits

📘 3. 块大小(Block Size)

每次从内存载入Cache的一单位是一个块(Block):

  • 题目中:Block Size = 4 KB = 2¹² Bytes

  • 所以:一个Block中的 Block Offset 需要 12 bits 来寻址

📘 4. 缓存大小(Cache Size)

Cache的总容量为:1 MB = 2²⁰ Bytes

因为每个Block为2¹² Bytes,所以Cache中可以容纳的Block数为:

Number of Blocks in Cache = 2²⁰ Bytes / 2¹² Bytes = 2⁸ Blocks
=> Index 位数 = 8 bits

📘 5. 直接映射(Direct Mapping)

在直接映射结构中,一个内存块只能映射到Cache中的某一个固定位置:

  • 物理地址 PA 被划分为三个字段:

[ Tag | Index | Block Offset ]

PA Bits Split(物理地址位分割)

我们已经有:

  • 总物理地址位数 = 32 bits

  • Block Offset = 12 bits(由 Block Size 决定)

  • Index = 8 bits(由 Cache block 数量决定)

  • 所以剩下的是:Tag = 32 - 8 - 12 = 12 bits

字段(中文)字段(英文)位数(bits)来源说明
标签位Tag Bits12 bitsPA剩余位
索引位Index Bits8 bits2⁸ 个block
块内偏移Block Offset12 bits4 KB block

 

📁 Tag Directory(标签目录) 是什么?

标签目录是缓存中用于记录哪个主存块现在存放在 Cache 的哪个行的标签表。

它确实是“按 cache 行组织”的,也就是:

每一个 Cache Line(缓存行),都对应一条 Tag Directory 的记录!

我们记录的是,当前每个 Cache Line 对应的 Memory Block 的 Tag。

更严谨一点说:

  • 主存块数 >> Cache 行数

  • 所以多个主存块可能映射到同一个 Cache Line

  • 为了区分是谁占了这个 Cache Line,就要存下那个主存块的 “Tag”

每一条记录通常包含:

  • Tag(标签):用来标识当前Cache Block对应的内存块

  • Valid Bit(有效位):表示该块是否有效

  • (可选)Dirty Bit(脏位):在写回法中表示是否被修改

🔸 本题只要求考虑 Tag 本身,忽略 Valid/Dirty 位。 

📐 Tag Directory 的大小计算方法

步骤一:计算 Cache 行数(即 Cache lines)

每行存一个 Block:

Cache lines = Cache size / Block size= 2²⁰ / 2¹²= 2⁸

所以 Cache 有 256 行(2⁸)

 步骤二:Tag 位数计算

  • 物理地址总长:32 bits

  • Block Offset = 12 bits(由块大小决定)

  • Index = 8 bits(由 Cache 行数决定)

Tag 位数 = 32 - Index - Block Offset= 32 - 8 - 12= 12 bits

步骤三:Tag Directory 大小

只记录 Tag 位(不考虑 Valid/Dirty):

Tag Directory size = Number of cache lines × Tag bits= 2⁸ × 12 bits= 256 × 12 = 3072 bits= 384 Bytes

例题二

因为 Block Size = Line Size,你可以直接用下面这个公式算: 

Tag 位数 = log₂(MM Size / Cache Size)

因为由MM Size : Cache Size 的值,我们可以知道映射到Cache某一行(line)的有多少块(Block)。

上图的实例表明,4个块映射到同一行。 

例题三 

例题四

一个直接映射缓存(Direct Mapped Cache)大小为 1MB,块大小为256字节(Bytes)。

  • 缓存命中时的访问时间是 3纳秒(ns)。

  • 缓存命中率为 94%。

  • 当发生 缓存未命中(miss) 时:

    • 第一个字从主存中传输需要 20ns

    • 其余每个字的传输时间为 5ns/字

  • 一个字(Word)的大小是 64位 = 8字节

问题: 求平均内存访问时间(Average Memory Access Time, AMAT),精确到小数点后1位。

串行访问还是并行访问的选择 

在计算主存访问时间时,如果题目中给出的是:

  • “first word takes X ns”

  • “each subsequent word takes Y ns”

就要问自己:

❓ 是并行加载所有字,还是一个接一个串行加载? 

这道题的正确思路是:

🔸 这是串行传输(Serial Transfer)!

 

理由如下:

  • 题目中明确说:

    • 第一字传输用 20ns

    • 后续每字用 5ns

  • 如果是并行传输,那就应该是一次性所有字只用最长那个时间。但这里强调“每个”说明是串行!

关于这方面(串行访问与并行访问)的具体内容,可以在这篇文章中查看:

计算机组成与体系结构:内存接口(Memory Interface)-CSDN博客

例题五 

 例题六

例题七 

 

一台 CPU 配备了一个32KB大小的直接映射(Direct-Mapped)缓存,块大小为128字节。
现在有一个二维数组 A,尺寸是512 × 512,每个元素占用8字节。

考虑下面两个独立执行的 C 代码段 P1 和 P2:

P1:按 行优先(row-major)顺序访问数组。 

P2:按 列优先(column-major)顺序访问数组。 

初始条件: A数组一开始不在缓存中,i、j、x 都在寄存器中。

问题:

执行P1时,缓存未命中次数记为 M1。执行P2时,缓存未命中次数记为 M2。

计算并选择 M1/M2 的值

 

 一个 Cache Block 可存储:

128 Bytes / 8 Bytes per element = 16 elements

即一个块可以装下连续16个元素(在内存中连续的)。 

🔵 P1:(按行访问)

 

特点:

  • 内存是行优先存储(Row-Major),

  • A[i][j]A[i][j+1] 在内存中是连续的。

  • 一个 Cache Block 可以放下 16 个元素。

一次 miss 后,可以利用的连续缓存:

  • 第一次访问 A[i][0]:miss

  • 然后 A[i][1] ~ A[i][15]:全是 hit!(因为它们都在同一个缓存块中)

  • 直到访问到 A[i][16],再 miss。

所以:
每访问 16 个元素只 miss 1 次

每一行有 512 个元素,划分成:512 / 16 = 32块

每一行就有 32 次 miss。

M1 = 512 × 32 = 16,384 次

🔴 P2:(按列访问)

 

特点:

  • 列优先访问,但是内存按行优先存储。

  • A[j][i]A[j+1][i] 在内存中 不连续。

  • A[0][i]A[1][i] 分别在不同的行,相隔 512×8=4096 Bytes。

  • 它们肯定不在同一个 Cache Block。

所以:

  • 每访问一个元素 A[j][i],都会导致 一次 miss!

  • 因为访问的是不同缓存块(地址跳得太大),缓存局部性被破坏了。

全局总miss:

  • 总访问次数 = 512 × 512 = 262,144 次

  • 每次都 miss

所以:

M2 = 262,144 次

为什么一定会有miss? 

实际上 miss 并不是一定存在的,它取决于当时 Cache 里的数据和你访问的数据是不是吻合。

但是,在某些特定情况下,一开始访问必然会miss,比如: 

特别情况:

  • 题目明确说了:"数组A一开始不在缓存中"。

  • 所以当我们第一次访问数组A的任意元素时,必然miss!

  • 后续如果继续访问已经加载到Cache里的数据,就可能hit。

为什么按行访问和按列访问的 Miss 不一样?

这要结合访问方式来看:

在按行访问(P1)时:

  • 因为元素在内存中是连续的。

  • 一个 Cache Block 可以放 16 个元素。

  • 第一个元素 miss,后面 15 个元素 hit(空间局部性好)。

  • 所以不是每次访问都 miss,每16个元素只miss 1次。

在按列访问(P2)时:

  • 访问顺序是跳着走的:

    • A[0][i]A[1][i]A[2][i] ……

  • 每次跳跃4096 Bytes(因为数组按行存,每行512×8=4096 Bytes)。

  • 跳得太远,Cache块根本无法覆盖这么远的跨度。

  • 而且是直接映射缓存,不同地址很容易映射到同一个Cache行,导致原来装的数据被替换掉。

因此在列访问中:

每次访问基本都是新的块,所以每次访问都会miss! 

 例题八

考虑一台主存为 2^16 字节、按字节寻址(byte-addressable)的计算机。
系统中使用一个直接映射(Direct Mapped)数据缓存,缓存由32行(lines)组成,每行大小为64字节。

有一个大小为 50×50 的二维字节数组,存储在主存中,从地址 1100H(十六进制)开始。

假设:

  • 数据缓存初始为空。

  • 完整访问这个数组两遍。

  • 在两次访问之间,缓存内容不会变化(不会刷新)。

问题:

i. 访问两遍数组,总共有多少次缓存未命中(Cache Miss)?
选项:

  • (A) 40

  • (B) 50

  • (C) 56

  • (D) 59

ii. 在第二次访问数组时,会替换缓存中哪些行?
选项:

  • (A) line 4 到 line 11

  • (B) line 4 到 line 12

  • (C) line 0 到 line 7

  • (D) line 0 到 line 8

 基础参数

 

 

第一次访问: 

从地址1100H 开始,依次访问 2500个元素。 

因为一个 Cache Block 装64个字节, 

  • 向上取整 → 需要 40个块(因为最后一块可能不满,但仍然需要加载)。

 所以第一次访问会造成 40次miss(每次加载一个新的缓存块)。

 

 

地址冲突

第二次访问:

  • 由于"缓存内容不会变化",所以如果之前访问的数据仍然在 Cache 中,就不会miss。

  • 但是!因为是直接映射,地址冲突可能导致 Cache Line 被替换!

 

 

http://www.xdnf.cn/news/162019.html

相关文章:

  • 大模型微调与蒸馏的差异性与相似性分析
  • 字节跳动开源数字人模型latentsync1.5,性能、质量进一步优化~
  • 1.1.1 用于排序规则的IComparable接口使用介绍
  • 【MinIO实战】MinIO权限策略设置与上传文件时报错Access Denied排查
  • 03.01、三合一
  • CentOS7 部署 Ollama 全栈指南:构建安全远程大模型服务
  • 【Python】Python中的浅拷贝和深拷贝
  • Halcon算子应用和技巧13
  • Spring AI Alibaba - Milvus 初体验,实现知识库效果
  • SDC命令详解:使用reset_design命令重置设计
  • 力扣热题100题解(c++)—链表
  • Python项目实践:控制台银行系统与词频统计工具开发指南
  • c#简易超市充值卡程序充值消费查余额
  • 升级 Spring Boot CLI
  • 信用中国【国密SM2、SM4加解密】逆向算法分析
  • 【学习笔记】Stata
  • CD32.【C++ Dev】类和对象(22) 内存管理(下)
  • 在线录屏工具(压箱底)-免费高清
  • 基于QT的仿QQ音乐播放器
  • Pygame精灵进阶:动画序列与角色控制
  • 信息论核心概念详解
  • 利用【指针引用】对【非空单循环链表】进行删除操作
  • 服务器虚拟化:技术解析与实践指南
  • 协程(微线程)
  • Kdenlive 中的变形、畸变、透视相关功能
  • Python函数基础:简介,函数的定义,函数的调用和传入参数,函数的返回值
  • 架构整洁之道 心得
  • 【线段树】P11414 [EPXLQ2024 fall round] 神奇磁铁|普及+
  • 如何在 PowerShell 脚本中调用外部 Windows 命令
  • 精益数据分析(29/126):深入剖析电子商务商业模式