《计算机组织结构》期末复习-第9讲-外部存储器
第9讲-外部存储器
外部存储器
特性:用于存储不经常使用的、数据量较大的信息;非易失。
类型:
磁盘存储器(magnetic disk disk)
光存储器(optical memory memory)
磁带(magnetic tape tape)
U盘(USB flash disk disk)
固态硬盘(solid state disk disk,SSD)
磁盘
磁盘是由涂有可磁化材料的非磁性材料(基材)构成的圆形盘片
基材:铝、铝合金、玻璃
玻璃基材的优势(稳定可靠、为存储更多信息提供基础)
改善磁膜表面的均匀性,提高磁盘的可靠性
显著减少整体表面瑕疵,以帮助减少读写错误
能够支持(磁头)较低的飞行高度
更高的硬度,使磁盘转动时更加稳定
更强的抗冲击和抗损伤能力
类型:硬盘、软盘
磁头:对盘片进行读写操作的装置
磁盘存储器每个盘片表面有一个读写磁头,所有磁头通过机械方式固定在一起,同时移动。在任何时候,所有磁头都位于距磁盘中心等距离的磁道上。
磁头必须产生或感应足够大的电磁场,以便正确地读写
磁头越窄,电磁感应能力越弱,离盘片的距离就越近
更高的数据密度需要更窄的磁头 ...
《计算机组织结构》期末复习-第8讲-高速缓冲存储器
第8讲-高速缓冲存储器
Cache的目的和基本思路
问题:CPU的速度比内存的速度快,且两者差距不断扩大—内存墙。
解决:CPU和内存之间增加Cache。
解决内存墙带来的CPU和主存协作问题
在使用主存(相对大而慢)之余,添加一块小而快的cache
Cache位于CPU和主存之间,可以集成在CPU内部或作为主板上的一个模块
Cache中存放了主存中的部分信息的“副本”
Cache的工作流程
检查(Check):当CPU试图访问主存中的某个字时,首先检查这个字是否在cache中
检查后分两种情况处理:
命中(Hit):如果在cache中,则把这个字传送给CPU
未命中(Miss):如果不在cache中, 则将主存中包含这个字固定大小的块(block)读入cache中,然后再从cache传送该字给CPU
如何判断是命中还是未命中?
Cache通过标记(tags)来标识其内容在主存中的对应位置
局部性原理
定义:处理器频繁访问主存中相同位置或者相邻存储位置的现象。
时间局部性:在相对较短的时间周期内,重复访问特定的信息(也就是访问相同存储位置的信息)
空间局部性:在 ...
《计算机组织结构》期末复习-第7讲-内部存储器
第7讲-内部存储器
存储器(Memory)
定义:存储器(Memory)由一定数量的单元构成,每个单元可以被唯一标识,每个单元都 有存储一个数值的能力
地址:单元的唯一标识符(采用二进制)
地址空间:可唯一标识的单元总数
寻址能力:存储在每个单元中的信息的位数,即内存中能被单独识别并独立存放一个数据的最小内存空间— 大多数存储器是字节(8bit)寻址的,32位计算机的最大寻址空间为4GB
层次结构
主板内存储器:寄存器,Cache,主存。
主板外存储器:磁盘,CD-ROM,CD-RW,DVD-RW,DVD-RAM。
离线存储器:磁带
AND-OR锁存器参考文章:谁能告诉我AND-OR锁存器原理? - 知乎 (zhihu.com)先解释OR锁OR锁:
OR门B输入和输出连接。INIT为初始状态A=B=0;当A=1,B=0时,OUTPUT变为1同时将B变为1;此时,当A变回0,OUTPUT仍为1(被锁住)。
AND锁:
AND门B输入和输出连接。
INIT为初始状态A=B=1;
当A=0,B=1时,OUTPUT变为0同时将B变为0;
此时,当A变回1,OUTPUT仍 ...
《计算机组织结构》机试复习
数据的机器级表示1.将整数真值(十进制表示)转化成补码表示的二进制,默认长度32位。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748public static String intToBinary(String numStr) { int num = Integer.parseInt(numStr); if(num == Integer.MIN_VALUE) return "10000000000000000000000000000000"; boolean neg = false; if(num < 0) { num = -num; neg = true; } StringBuilder temp = new StringBuilder(); while(num > 0) { temp.insert ...
一些数学
快速幂
12345678int pow(int a, int b, int m) { int ans = 1; for (; b; b >>= 1) { if (b & 1) ans = (LL)ans * a % m; a = (LL)a * a % m; } return ans;}
龟速乘
12345678910LL mul(LL a, LL b, LL p) { a %= p; b %= p; LL c = (double)a * b / p; LL x = a * b; LL y = c * p; LL ans = (LL)(x % p) - (LL)(y % p); if (ans < 0) ans += p; return ans;}
等比数列(公比为p,项数为e,以1为首项)
123456789int sum(int p, int e, int m) { if (e == 1) return 1; if (e % 2 == 0) ...
石子合并问题
石子合并问题:有N堆石子,现要将石子有序的合并成一堆,规定如下:每次只能移动相邻的2堆石子合并,合并花费为新合成的一堆石子的数量。求将这N堆石子合并成一堆的总花费最小(或最大)。
这是一道典型的动态规划题目。令dp[i][j]为将第i到j堆石子合并成一堆的最小代价w[i][j]为第i到j堆石子的总数。就可以写出状态转移方程:
dp[i][j] = min_{k=i}^{j-1}(dp[i][k] + dp[k+1][j]) + w[i][j]直接暴力求解就可以,复杂度O(n3)。
改进方法是用平行四边形不等式优化,缩小k的范围,复杂度O(n2) :算法学习笔记(79): 四边形不等式优化DP - 知乎 (zhihu.com)
问题的变种是让石子环形排列,即第一堆和最后一堆看成是相邻的。解决方法是在n堆石子后面再加上与前面一样的n堆石子,这样最后一堆和第一堆就相邻了。把总堆数看成2n,用上面的方法解出来就可以了。最后还需要遍历一下dp数组,求出2n堆石子里面结果最小的n堆石子作为最终结果。
P1880 [NOI1995] 石子合并 - 洛谷 | 计算机科学教育新生态 (luogu.co ...
Sparse Table(稀疏表)
Sparse Table简称ST,用于对一组静态数据进行区间查询。
例如:
RMQ:区间最大(最小)值
RGQ:区间最大公因数
这两个问题都可以用线段树解决。但线段树的查询时间是O(logn),ST可以在O(1)时间内完成查询。代价是是ST不能对数组进行动态维护,数组在查询之前就固定下来。因此,如果需要动态维护数组,用线段树;反之,用ST。
什么样的问题可以用ST解决?例如说,求区间最小值,我们可以先把一个区间分成两个小区间,两个小区间的的最小值就是大区间的最小值。最大公因数也同理,求一个大区间的最大公因数,先求两个小区间的最大公因数,再求这两个数的最大公因数就是大区间的最大公因数。类似这类问题都能用ST解决。形式化的,ST能解决的问题为:
求数组的某一区间S的某一性质F(S),性质F满足:
若{s_1}\cup {s_2}=S,则F(S)=F(F(s_1),F(s_2)).可以验证,min和gcd都满足以上要求。
详细内容参照这篇文章算法笔记-CSDN博客](https://blog.csdn.net/narcissus2_/article/details/89423591 ...
[leetcode]315. 计算右侧小于当前元素的个数
力扣315,没有花里胡哨的题面,属于树状数组的模版题了。正好复习一下BIT。先看题目:
[计算右侧小于当前元素的个数]
Category
Difficulty
Likes
Dislikes
algorithms
Hard (43.45%)
1032
-
给你一个整数数组 nums ,按要求返回一个新数组 counts 。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。
示例 1:
1234567输入:nums = [5,2,6,1]输出:[2,1,1,0] 解释:5 的右侧有 2 个更小的元素 (2 和 1)2 的右侧仅有 1 个更小的元素 (1)6 的右侧有 1 个更小的元素 (1)1 的右侧有 0 个更小的元素
示例 2:
12输入:nums = [-1]输出:[0]
示例 3:
12输入:nums = [-1,-1]输出:[0,0]
看完题目,很自然想到用树状数组来做。关于树状数组,可以参考这篇文章:算法学习笔记(2) : 树状数组 - 知乎 (zhihu.com)
思路大概是:
通过排序 ...
ICS-PA3 实验记录
记录一下pa的完成过程。前面的pa1和pa2没有记录,等以后有机会二刷再补上吧。
PA3-1PA3的第一阶段是实现异常响应机制。为实现异常响应,需要添加几个特殊寄存器,称为控制和状态寄存器(CSR)。PA中需要用到的包括:
CSR
功能
mepc
存放触发异常的PC
mcause
存放触发异常的原因
mstatus
存放处理器的状态
mtvec
存放异常入口地址
触发异常前,需要调用cte_init()函数进行初始化,将异常入口地址存到mtvec寄存器中,并注册一个事件处理回调函数,当触发异常时,将会以上下文信息和信息为参数调用此回调函数,执行异常处理操作。
RISCV32通过ecall指令触发自陷。具体来说,ecall指令执行的操作为:
CSR[mepc] <- pc
CSR[mcause] <- 异常号
PC <- CSR[mtvec] (执行异常响应程序)
完成异常响应程序后,恢复上下文信息,通过mret指令将PC从mepc中恢复(并+4),从中断处继续执行。
大致理解机制之后,再RTFM和RTFSC之后就可以敲代码了。 ...
Hello, world!
诞生于2023/11/14。