Peiqin

时间有限,不要在此停留太久

0%

  计算机理论知识概念001

内容来源于维基,相对有参考的价值,越是基础,越不能有半点差池。

计算机存储器,存储结构,虚拟内存,寄存器,CPU缓存

计算机存储器

计算机存储器(英语:Computer memory)是一种利用半导体、磁性介质等技术制成的存储资料的电子设备。其电子电路中的资料以二进制方式存储,不同存储器产品中基本单元的名称也不一样。

计算机存储器可分为内部存储器(又称内存或主存)和外部存储器,其中内存是CPU能直接寻址的储存空间,由半导体器件制成。内存的特点是访问速率快。我们平常使用的程序,如Windows操作系统、打字软件、游戏软件等,一般都是安装在硬盘等外部记忆体上的,但必须把它们调入内存中运行,才能真正使用其功能,我们平时输入一段文字,或玩一个游戏,其实都是在内存中进行的,数据产生后不断地由内存向外部记忆体进行读写。就好比在一个书房里,存放书籍的书架和书柜相当于电脑的外部记忆体,而我们工作的办公桌就是内存。通常我们把要永久保存的、大量的数据储存在外部记忆体上,而把一些临时的或少量的数据和程序放在内存上,当然内存的好坏会直接影响电脑的运行速度

容量

存储器以二进制计算容量,基本单位是Byte

  • 1 Kilobyte(KB) =1,024B=210B
  • 1 Megabyte(MB)=1,024KiB=220B=1,048,576B
  • 1 Gigabyte(GB)=1,024MiB=230B=1,073,741,824B
  • 1 Terabyte(TB)=1,024GiB=240B=1,099,511,627,776B
  • 1 Petabyte(PB)=1,024TiB=250B=1,125,899,906,842,624B
  • 1 Exabyte(EB) =1,024PiB=260B=1,152,921,504,606,846,976B
  • 1 Zettabyte(ZB)=1,024EiB=270B
  • 1 Yottabyte(YB)=1,024ZiB=280B

根据电气电子工程师协会(IEEE 1541)和欧洲联盟(HD 60027-2:2003-03)的标准,二进制乘数词头的缩写为“Ki”、“Mi”、“Gi”,以避免与SI Unit国际单位制混淆。但二进制乘数词头没有广泛被制造业和个人采用,标示为4GB的内存实际上已经是4GiB,但标示为4.7GB的DVD实际上是4.37GiB。

对于32位的操作系统,最多可使用232个地址,即是4GiB。物理地址扩展可以让处理器在32位操作系统访问超过4GiB存储器,发展64位处理器则是根本的解决方法,但操作系统驱动程序应用程序都会有兼容性问题。

分类

计算机存储器可以根据存储能力与电源的关系可以分为以下两类:

易失性存储器

易失性存储器(Volatile memory)是指当电源供应中断后,存储器所存储的资料便会消失的存储器。主要有以下的类型:

随机存取存储器

  • 动态随机存取存储器,英文缩写写作DRAM,一般每个单元由一个晶体管和一个电容组成(后者在集成电路上可以用两个晶体管模拟)。特点是单元占用资源和空间小,速度比SRAM慢,需要刷新。一般计算机主内存即由DRAM组成。在PC上,DRAM以内存条的方式出现,DRAM颗粒多为4位或8位位宽,而载有多个颗粒的单根内存条的位宽为64位。
  • 静态随机存取存储器,英文缩写写作SRAM,一般每个单元由6个晶体管组成,但近来也出现由8个晶体管构成的SRAM单元。特点是速度快,但单元占用资源比DRAM多。一般CPUCPU缓存即由SRAM构成。
非易失性存储器

非易失性存储器(Non-volatile memory)是指即使电源供应中断,存储器所存储的资料并不会消失,重新供电后,就能够读取存储器中的资料。 主要种类如下:

  • 只读存储器

    (ROM)

    • 可编程式只读存储器(PROM)
    • 可擦除可规划式只读存储器(EPROM)
    • 电子抹除式可复写只读存储器(EEPROM)
    • Flash ROM
  • 磁存储

    • 硬盘
    • 软盘
    • 磁带
  • 3D XPoint

  • 固态硬盘

  • 光存储

    • 光盘

存储层次

存储层次是在计算机体系结构存储系统层次结构的排列顺序。每一层于下一层相比都拥有较高的速度和较低延迟性,以及较小的容量(也有少量例外,如AMD早期的Duron CPU)。大部分现今的中央处理器的速度都非常的快。大部分程序工作量需要存储器访问。由于高速缓存的效率和存储器传输位于层次结构中的不同等级,所以实际上会限制处理的速度,导致中央处理器花费大量的时间等待存储器I/O完成工作。

大部分电脑中的存储层次如下四层:

1) 寄存器–可能是最快的访问。在32位处理器,每个寄存器就是32位。x86处理器共有16个寄存器。

2) 高速缓存(L1-L3: SRAM

3) 主存DRAM)–访问需要几百个周期,可以大到数十GB。

4) 磁盘存储–需要成千上百个周期,容量非常大。

虚拟内存

虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存(例如RAM)的使用也更有效率。

注意:虚拟内存不只是“用磁盘空间来扩展物理内存”的意思——这只是扩充内存级别以使其包含硬盘驱动器而已。把内存扩展到磁盘只是使用虚拟内存技术的一个结果,它的作用也可以通过覆盖或者把处于不活动状态的程序以及它们的数据全部交换到磁盘上等方式来实现。对虚拟内存的定义是基于对地址空间的重定义的,即把地址空间定义为“连续的虚拟内存地址”,以借此“欺骗”程序,使它们以为自己正在使用一大块的“连续”地址。

现代所有用于一般应用的操作系统都对普通的应用程序使用虚拟内存技术,例如文字处理软件,电子制表软件,多媒体播放器等等。老一些的操作系统,如DOS和1980年代的Windows,或者那些1960年代的大型机,一般都没有虚拟内存的功能——但是Atlas(英语:Atlas_(computer)),B5000(英语:Burroughs_large_systems#B5000)和苹果公司Lisa都是很值得注意的例外。[1]

那些需要快速访问或者反应时间非常一致的嵌入式系统,和其他的具有特殊应用的计算机系统,可能会为了避免让运算结果的可预测性降低,而选择不使用虚拟内存。

寄存器

寄存器(Register)是中央处理器内用来暂存指令、数据地址电脑存储器。寄存器的存贮容量有限,读写速度非常快。在计算机体系结构里,寄存器存储在已知时间点所作计算的中间结果,通过快速地访问数据来加速计算机程序的运行。

寄存器位于存储器层次结构的最顶端,也是CPU可以读写的最快的存储器。寄存器通常都是以他们可以保存的比特数量来计量,举例来说,一个8位寄存器或32位寄存器。在中央处理器中,包含寄存器的部件有指令寄存器(IR)、程序计数器累加器。寄存器现在都以寄存器数组的方式来实现,但是他们也可能使用单独的触发器、高速的核心存储器薄膜存储器以及在数种机器上的其他方式来实现出来。

寄存器也可以指代由一个指令之输出或输入可以直接索引到的寄存器组群,这些寄存器的更确切的名称为“架构寄存器”。例如,x86指令集定义八个32位寄存器的集合,但一个实现x86指令集CPU内部可能会有八个以上的寄存器。

寄存器的种类

资料寄存器

用来存储整数数字(参考以下的浮点寄存器)。在某些简单(或旧)的CPU,特别的资料寄存器是用于数学计算的累加器

地址寄存器

持有存储器地址,以及用来访问存储器。在某些简单/旧的CPU里,特别的地址寄存器是索引寄存器(可能出现一个或多个)。

通用目的寄存器

GPRs)- 可以保存资料或地址两者,也就是说他们是结合 资料/地址 寄存器的功用。

浮点寄存器

FPRs)- 用来存储浮点数字。

常量寄存器

用来持有只读的数值(例如0、1、圆周率等等)。由于“其中的值不可更改”这一特殊性质,这些寄存器未必会有实体的硬件电路相对应,例如将从零常数寄存器读的操作实现为接通目标寄存器的下拉电阻

一般而言,即使真正在硬件中放置常数寄存器也未必会是出于体系结构理论上的考虑,而很可能是由硬件描述语言为了简化操作而自动生成的电路。

向量寄存器

用来存储由向量处理器运行SIMD指令所得到的资料。

特殊目的寄存器

存储CPU内部的资料,像是程序计数器(或称为指令指针),堆栈寄存器,以及状态寄存器(或称微处理器状态字组)。

  • 指令寄存器 - 存储现在正在被运行的指令

  • 变址寄存器(英语:Index_register - 是在程序运行时用来更改操作数地址之用。

  • 在某些架构下,模式指示寄存器(也称为“机器指示寄存器”)存储和设置跟处理器自己有关的资料。由于他们的意图目的是附加到特定处理器的设计,因此他们并不被预期会成微处理器世代之间保留的标准。

  • 有关从

    随机存取存储器

    提取信息的寄存器与CPU(位于不同芯片的存储寄存器集合)

    • 存储器缓冲寄存器(英语:Memory buffer register
    • 存储器资料寄存器
    • 存储器地址寄存器(英语:Memory address register
    • 存储器类型范围寄存器(英语:Memory Type Range Registers

cup缓存是个复杂的概率,以下暂时列出基本描述,是不完整的,读者要注意一下。

cup缓存

计算机系统中,CPU高速缓存(英语:CPU Cache,在本文中简称缓存)是用于减少处理器访问内存所需平均时间的部件。在金字塔式存储体系中它位于自顶向下的第二层,仅次于CPU寄存器。其容量远小于内存,但速度却可以接近处理器的频率。

当处理器发出内存访问请求时,会先查看缓存内是否有请求数据。如果存在(命中),则不经访问内存直接返回该数据;如果不存在(失效),则要先把内存中的相应数据载入缓存,再将其返回处理器。

缓存之所以有效,主要是因为程序运行时对内存的访问呈现局部性(Locality)特征。这种局部性既包括空间局部性(Spatial Locality),也包括时间局部性(Temporal Locality)。有效利用这种局部性,缓存可以达到极高的命中率。

在处理器看来,缓存是一个透明部件。因此,程序员通常无法直接干预对缓存的操作。但是,确实可以根据缓存的特点对程序代码实施特定优化,从而更好地利用缓存。

基本描叙
缓存的存储结构

结构上,一个直接映射(Direct Mapped)缓存由若干缓存块(Cache Block,或Cache Line)构成。每个缓存块存储具有连续内存地址的若干个存储单元。在32位计算机上这通常是一个双(dword),即四个字节。因此,每个双字具有唯一的块内偏移量。

每个缓存块有一个索引(Index),它一般是内存地址的低端部分,但不含块内偏移和字节偏移所占的最低若干位。一个数据总量为4KB、缓存块大小为16B的直接映射缓存一共有256个缓存块,其索引范围为0到255。使用一个简单的移位函数,就可以求得任意内存地址对应的缓存块的索引。由于这是一种多对一映射,必须在存储一段数据的同时标示出这些数据在内存中的确切位置。所以每个缓存块都配有一个标签(Tag)。拼接标签值和此缓存块的索引,即可求得缓存块的内存地址。如果再加上块内偏移,就能得出任意一块数据的对应内存地址。

因此,在缓存大小不变的情况下,缓存块大小和缓存块总数成反比关系。下图中所示的缓存块来自一个数据总量为4KB、每个缓存块大小为16B的直接映射缓存,其标签长度为20bits。

一个大小为16字节的缓存块。从属于一个数据总量为4KB的直接映射缓存。

此外,每个缓存块还可对应若干标志位,包括有效位(valid bit)、脏位(dirty bit)、使用位(use bit)等。这些位在保证正确性、排除冲突、优化性能等方面起着重要作用。

运作流程

下面简要描述一个假想的直接映射缓存的工作流程。这个缓存共有四个缓存块,每个块16字节,即4个字,因此共有64字节存储空间。使用写回(Write back)策略以保证数据一致性。

img

CPU缓存的运作流程(注意内存左侧给出的地址是字地址而不是字节地址)

系统启动时,缓存内没有任何数据。之后,数据逐渐被载入或换出缓存。假设在此后某一时间点,缓存和内存布局如右图所示。此时,若处理器执行数据读取指令,控制逻辑依如下流程:

  1. (将地址由高至低划分为四个部分:标签、索引、块内偏移、字节偏移。其中块内偏移和字节偏移各占两位,后者在以下操作中不使用。)
  2. 用索引定位到相应的缓存块。
  3. 用标签尝试匹配该缓存块的对应标签值。如果存在这样的匹配,称为命中(Hit);否则称为未命中(Miss)。
  4. 如命中,用块内偏移将已定位缓存块内的特定数据段取出,送回处理器。
  5. 如未命中,先用此块地址(标签+索引)从内存读取数据并载入到当前缓存块,再用块内偏移将位于此块内的特定数据单元取出,送回处理器。这里要注意的是,(1)读入的数据会冲掉之前的内容。为保证数据一致性,必须先将数据块内的现有内容写回内存。(2)尽管处理器请求的只是一个字,缓存仍必须在读取的时候把整个数据块都填充满。(3)缓存的读取是按缓存块大小为边界对齐的。对于大小为16字节的缓存块,任何因为0x0000、或0x0001、或0x0002、或0x0003造成的未命中,都会导致位于内存0x0000—0x0003的全部四个字被读入块中。

在右图中,如此时处理器请求的地址在0x0020到0x0023之间,或在0x0004到0x0007之间,或在0x0528到0x052B之间,或在0x05EC到0x05EF之间,均会命中。其余地址则全部未命中。

而处理器执行数据写入指令时,控制逻辑依如下流程:

  1. 用索引定位到相应的缓存块。
  2. 用标签尝试匹配该缓存块的对应标签值。其结果为命中或未命中。
  3. 如命中,用块内偏移定位此块内的目标字。然后直接改写这个字。
  4. 如未命中,依系统设计不同可有两种处理策略,分别称为按写分配(Write allocate)和不按写分配(No-write allocate)。如果是按写分配,则先如处理读未命中一样,将未命中数据读入缓存,然后再将数据写到被读入的字单元。如果是不按写分配,则直接将数据写回内存。