《计算机组成原理》 存储系统
words: 3.1k views: time: 11min存储器是计算机的核心部件之一,用于存储程序和数据。由于现代计算机对于存储器容量和速度的要求越来越高,使得存储器以及演变成了存储系统
存储器层次
在CPU内部有少量的寄存器可以存储正在执行的指令或者正在参加运算的数据,寄存器访问非常快,但数量少;
对于正在运行的程序的指令和数据存放在CPU可以直接访问的主存储器中,称为主存;
在主存之外,为了扩大存储容量会增加一些容量大但是访问较慢的辅助存储器,比如硬盘;CPU不能直接访问外存储器,外存储器的数据需要调用主存后才能由CPU访问;
随着技术发展,CPU和主存的工作速度都在提高,但CPU提高得更快,于是又在CPU和主存之间增加了一层高速缓存(cache),出于对性能的要求,高速缓存本身又可以分成三级,即L1、L2、L3。
因此,现在的存储系统一般分为三级,即由cache、主存和外存储器构成,其中cache主要用于提高访问速度,而外存储器用于提高存储容量问题。
虚存储器
在早期单用户但任务操作系统中(比如DOS),每台计算机只有一个用户,每次只运行一个,且程序不是很大,因此完全可以存储在主存中没问题。
随着多用户多任务系统的出现,以及程序占用存储越来越大,在程序设计时,程序所需的存储容量与计算机实际的主存容量之间往往存在矛盾。而在多用户多任务共享主存的场景下,这些同时运行的程序到底占用内存中哪一部分,在编制程序时是无法确定的,必须等到程序运行时才动态分配。
因此,希望在编制程序时能独立编址,既不考虑程序是否能在物理存储器中存放得下,也不考虑程序应该存放在什么物理位置。而在程序运行时,则分配每个程序一定的运行空间,由地址转换器将编程时的地址转换为实际内存的物理地址。这样,用户编制程序时使用的地址称为虚地址或逻辑地址,而内存中对应的地址称为物理地址。
- 访问过程
用户程序按照虚地址编程并存放在辅助存储器中,当运行时,由地址转换器依据当时分配给程序的实际地址空间把程序的一部分调入主存。
每次访问时,首先判断虚地址对应的部分在主存中是否存在,如果存在,则转换为对物理地址的访问,否则按照某种算法将辅存中的部分程序调入主存中,再按同样的方法访问主存。所以通常虚地址空间可以远大于实际地址空间,比如可以top -M
看一下系统中的进程
有了虚存储机制后,应用程序就可以透明地使用整个虚地址空间,如果命中率很高,虚存的访问时间将接近于主存访问时间。由于虚存是在主存和辅存之外附加一些硬件和软件实现的,因此对于设计存储管理的系统程序员是不透明的,不过对于应用程序员而言仍然是透明地。
如果要实现虚存机制,至少要考虑以下问题:
- 调度问题:决定哪些程序和数据被调入主存;
- 地址映射问题:在访问主存时将虚地址转为主存的物理地址,以及在访问辅存时将虚地址转为辅存的物理地址,以便换页,此外还要解决主存分配、存储保护和程序再定位等问题;
- 替换问题:决定哪些程序和数据被调出主存;
- 更新问题:确保主存与辅存的一致性;
在操作系统的控制下,硬件和系统软件为用户解决了上述问题,从而使应用程序的编程大大简化。
页式虚拟存储器
页式虚拟存储系统中,虚地址和主存空间都被分成等长的页,分别称为逻辑页和物理页,至于地址则通过两个字段来描述,高字段为页号,低字段为页内偏移地址。
在大多数系统中,每个进程对应一个页表,页表中对应每一个虚存页面有一个表项,表项内容包含其对应的主存页面地址,以及表示该逻辑页是否已经调入主存的标识位。
但是每个进程所需的页数并不固定,有的进程可能需要很大的地址空间,因此页表可能很长,为了节约页表本身占用的主存空间,有的系统会采用二级分页,即每个进程有一个页目录表,其中的每个表项指向一个页表。
另外,由于页表本身存储在主存中,因而即使逻辑页已经在主存中,CPU也至少要访问两次主存才能获取一次数据,为了避免主存访问次数的增多,可以对页表本身实行二级缓存,把页表中活跃的部分放在高速缓存中,这个专门用于页表缓存的高速缓存通常称为转换后援缓冲器(TLB),也称为快表,而保存在主存中的完成页表则称为慢表,其目的是加快地址变换。
Linux内存管理
在Linux内存管理中,主要是通过调页Paging和交换Swapping来完成内存调度。调页算法是将内存中最近不常使用的页面换到磁盘上,把活动页面保留在内存中供进程使用。分页(Page)写入磁盘的过程被称作Page-Out,分页(Page)从磁盘重新回到内存的过程被称作Page-In。
当系统内核发现可运行内存变少时,就会通过Page-Out来释放一部分物理内存。如果Page-out频繁不断的发生,系统效能会急剧下降。这时的系统已经运行非常慢或进入暂停状态,这种状态也被称为thrashing(颠簸)。
- 命令:vmstat
vmstat是虚拟内存统计(Virtual Meomory Statistics)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监控。它提供了一种低开销的系统性能观察方式,即使在高负荷的服务器上也能查看并监控系统的健康情况,但它是对系统的整体情况进行统计,无法对某个进程进行深入分析。
格式:1
2
3
4
5
6
7vmstat [-a] [-n] [-S unit] [delay [ count]]
vmstat [-s] [-n] [-S unit]
vmstat [-m] [-n] [delay [ count]]
vmstat [-d] [-n] [delay [ count]]
vmstat [-p disk partition] [-n] [delay [ count]]
vmstat [-f]
vmstat [-V]
参数:1
2
3
4
5
6
7
8
9
10
11-a: 显示活跃和非活跃内存
-f: 显示从系统启动至今的fork数量 。
-m: 显示slabinfo
-n: 只在开始时显示一次各字段名称。
-s: 显示内存相关统计信息及多种系统活动数量。
delay:刷新时间间隔。如果不指定,只显示一条结果。
count:刷新次数。如果不指定刷新次数,但指定了刷新时间间隔,这时刷新次数为无穷。
-d: 显示磁盘相关统计信息。
-p: 显示指定磁盘分区统计信息
-S: 使用指定单位显示。参数有 k 、K 、m 、M ,分别代表1000、1024、1000000、1048576字节(byte)。默认单位为K
-V: 显示vmstat版本信息。
输出:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28r: 运行队列中进程数量(如果长期大于1的话,可能需要增加CPU)
b: 等待IO的进程数量
swpd: 使用虚拟内存大小(如果swpd不为0,但是si,so长期为0的话,这种情况不会影响系统性能)
free: 空闲物理内存大小
buff: 缓存文件元数据(inode 等)和来自原始块设备的数据
cache: 缓存文件数据块和内存映射信息(即调用mmap()映射的文件)
如果cache的值大,说明cache的文件数多,如果频繁访问的文件都能被cache处,那么磁盘的读IO bi会非常小。
si: 每秒从交换区写到内存的大小,由磁盘调入内存
so: 每秒写入交换区的内存大小,由内存调入磁盘
如果这si和so长期大于0,系统性能会受到影响,磁盘IO和CPU都会被消耗。有时看空闲内存(free)很少的或接近于0时,就认为内存不够用了。
其实不能光看这一点,还要结合si和so,如果free很少,但是si和so也很少,那么不用担心,系统性能这时不会受到影响
bi: 每秒读取的块数
bo: 每秒写入的块数
随机磁盘读写的时候,bi和bo越大,CPU花在IO等待上的值也会越大
in: 每秒中断数,包括时钟中断
cs: 每秒上下文切换数
us: 用户进程执行时间(user time)
sy: 系统进程执行时间(system time)
id: 空闲时间(包括IO等待时间),中央处理器的空闲时间 。以百分比表示。
wa: 等待IO时间
识别CPU瓶颈:当us
+ sy
接近于100时,表示CPU正接近于满负荷工作,但CPU满负荷工作并不能说明什么,Linux总会试图让CPU尽可能的繁忙,以便任务的吞吐量最大化,最能确定CPU瓶颈的还是r
,即队列中等待运行的进程数。
如果r
长期大于CPU个数(可以通过cat /proc/cpuinfo|grep processor|wc -l
查看CPU数),且id
很低,则说明cpu的负荷很重,一般出现这种情况,应用程序的问题会比较大一些,比如一些sql语句不合理的情况。
识别RAM内存瓶颈:通过虚拟内存机制,可以将RAM移到SWAP磁盘上,这样会出现虚拟内存的页导出和页导入现象,页导出并不能说明RAM瓶颈,虚拟内存系统经常会进行页导出,但经常出现页导入操作就表明服务器需要更多的内存了,页导入需要从SWAP复制回RAM,导致服务器速度变慢。即如果si和so长期非零的话,则可能存在内存瓶颈。
wa
表示CPU用于等待IO的时间,如果内存够大,可以修改文件/proc/sys/vm/swappiness
中的值,它表示实际内存区和交换区进行数据交换的倾向性大小,默认60,设置小一点以降低数据交换次数。但如果交换区Swap本身就使用很少,那么修改也没有意义,可能进程本身就是偏IO类型的任务。
示例:1
2
3
4
5
6
7procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 3476280 2116 229340 0 0 1 0 16 15 0 0 100 0 0
0 0 0 3476288 2116 229340 0 0 0 0 77 58 0 0 100 0 0
0 0 0 3476304 2116 229340 0 0 0 0 59 56 0 0 100 0 0
0 0 0 3476296 2116 229340 0 0 0 0 61 53 0 0 100 0 0
0 0 0 3476296 2116 229340 0 0 0 0 55 50 0 0 100 0 0
查看内存使用情况:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 3863576 K total memory
155384 K used memory
104780 K active memory
100092 K inactive memory
3476916 K free memory
2116 K buffer memory
229160 K swap cache
4193624 K total swap
0 K used swap
4193624 K free swap
2594 non-nice user cpu ticks
15 nice user cpu ticks
10945 system cpu ticks
19097245 idle cpu ticks
423 IO-wait cpu ticks
0 IRQ cpu ticks
596 softirq cpu ticks
0 stolen cpu ticks
169858 pages paged in
57641 pages paged out
0 pages swapped in
0 pages swapped out
3044881 interrupts
2914117 CPU context switches
1647746249 boot time
51300 forks
参考: