计算机组成 -- HDD
物理构造一块机械硬盘由盘面、磁头、悬臂三个部件组成 盘面 盘面(Disk Platter)是我们实际存储数据的盘片 盘面本身通常是用铝、玻璃或者陶瓷这样的材质去做成光滑盘片,然后在盘面上有一层磁性的涂层,数据就存储在磁性的涂层上 盘面中间有一个受电机控制的转轴(控制盘面去旋转),转速:RPM(Rotations Per Minute) 磁头 通过磁头(Drive Head),从盘面上读取数据,然后再通过电路信号传输给控制电路和接口,再到总线上 通常,一个盘面上会有两个磁头,分别是盘面的正反面,盘面在正反面都有对应的磁性涂层来存储数据 一块硬盘不会只有一个盘面,而且上下堆叠了很多个盘面,各个盘面之间是平行的,每个盘面的正反两面都有对应的磁头 悬臂 悬臂(Actutor Arm)链接在磁头上,并且在一定范围内去把磁头定位到盘面的某个特定磁道(Track)上 一个盘面通常是圆形的,由很多同心圆组成,每个同心圆都是一个磁道,每个磁道都有编号 随机读写 一个磁道,会分成多个扇区(Sector),上下平行的盘面的相同扇区,组成一个柱面(Cylinder) 数据读取的步骤 把盘面旋转到某个位置,在这个位...
计算机组成 -- IO_WAIT
IO性能 硬盘厂商的性能报告:响应时间(Response Time)、数据传输率(Data Transfer Rate) HDD硬盘一般用的是SATA 3.0的接口;SSD硬盘通常会用两种接口,一部分用SATA 3.0接口,另一部分用PCI Express接口 数据传输率 SATA 3.0接口的带宽是6Gb/s ≈ 768MB/s 日常用的HDD硬盘的数据传输率,一般在200MB/s SATA 3.0接口的SSD的数据传输率差不多是500MB/s PCI Express接口的SSD,读取时的数据传输率能到2GB/s,写入时的数据传输率也能有1.2GB/s,大致是HDD的10倍 响应时间 程序发起一个硬盘的读取或写入请求,直到请求返回的时间 SSD的响应时间大致在几十微秒这个级别,HDD的响应时间大致在十几毫秒这个级别,相差几十倍到几百倍 IOPS 每秒读写的次数,相对于响应时间,更关注IOPS这个性能指标 在顺序读写和随机读写的情况下,硬盘的性能是完全不同的 IOPS和DTR才是IO性能的核心指标 在实际的应用开发当中,对于数据...
计算机组成 -- IO设备
接口 + 设备 – 适配器模式 大部分的输入输出设备,都有两个组成部分,一个是接口,另一个是实际的IO设备 硬件设备并不是直接接入到总线上和CPU通信的,而是通过接口,用接口连接到总线上,再通过总线和CPU通信 串行接口、USB接口等都是计算机主板上内置的各个接口,实际使用的硬件设备,都需要插入到这些接口上,才能和CPU通信 接口本身是一块电路板,CPU不需要和实际的硬件设备打交道,只需要和这个接口电路板打交道 设备里面的三类寄存器(状态寄存器、命令寄存器、数据寄存器),都在接口电路上,而不在实际的设备上 除了内置在主板上的接口外,有些接口可以集成在设备上 – IDE(Integrated Device Electronics)硬盘 设备的接口电路直接在设备上,只需要通过一个线缆,把集成了接口的设备连接到主板上即可 接口和设备分离:各种输入输出设备的制造商,根据接口的控制协议,来设计各种外设 Windows设备管理器 Devices:着重实际的IO设备本身 Controllers:着重输入输出设备接口里面的控制电路 Adaptors:着重接口作为一个适配器后面可以插上不同的实际设备 C...
计算机组成 -- 总线
设计来源:降低复杂度 计算机内部有很多不同的硬件设备,除了CPU和内存,还有大量的输入输出设备 如果各个设备间的通信,都是互相之间单独进行的,如果有N个不同的设备,他们之间需要各自单独连接,那么系统复杂度为**$N^2$** 为了简化系统的复杂度,引入了总线,把**$N^2$复杂度,变成了$N$**的复杂度 CPU想要和什么设备通信,通信的指令是什么,对应的数据是什么,都发送到这个线路上 设备想要向CPU发送什么消息,也发送到这条线路上 这条线路好像一个高速公路,各个设备和其他设备之间,不需要单独建公路,只需要建一条小路通向这条高速公路即可 总线(Bus),其实就是一组线路,CPU、内存、输入输出设备,都是通过这组线路,进行相互间通信的 设计模式:事件总线 在大型系统开发的过程中,经常会用到一种叫作事件总线(Event Bus)的设计模式 系统中的各个组件之间需要相互通信,如果两两之间单独去定义协议,复杂度为**$N^2$** 各个模块触发对应的事件,并把事件对象发送到总线上,即每个模块都是一个发布者(Publisher) 各个模块也会把自己注册到总线上,去监听总线上的事件 并根据事件的对...
计算机组成 -- 内存
程序装载 在Linux或Windows下,程序并不能直接访问物理内存 内存需要被分成固定大小的页,然后通过虚拟内存地址到物理内存地址的地址转换,才能到达实际存放数据的物理内存位置 程序看到的内存地址,都是虚拟内存地址 地址转换简单页表 页表(Page Table,一一映射):<**虚拟**内存的页, **物理**内存的页> 页表:把一个内存地址分成页号(Directory)和偏移量(Offset)两部分 前面的高位,是内存地址的页号;后面的低位,是内存地址的偏移量 页表只需要保留虚拟内存地址的页号和物理内存地址的页号之间的映射关系即可 同一个页里面的内存,在物理层面是连续的 对于32位的内存地址,4KB大小的页,需要保留20位的高位,12位的低位 内存地址转换步骤 把虚拟内存地址,切分成页号和偏移量 从页表里面,查询出虚拟页号对应的物理页号 直接拿到物理页号,加上前面的偏移量,得到物理内存地址 空间问题 32位的内存地址空间,页表一共需要记录2^20个到物理页号的映射关系 一个页号是完整的32位的4 Bytes,一个页表就需要4MB的空间(2^20 * 4 Byt...
计算机组成 -- MESI协议
缓存一致性问题 iPhone降价了,要把iPhone最新的价格更新到主内存里,为了性能问题,采用写回策略 先把数据写入到L2 Cache里,然后把Cache Block标记为脏的 此时数据其实没有被同步到L3 Cache或主内存里 1号核心希望在这个Cache Block要被交换出去的时候,数据才写入到主内存里 此时2号核心尝试从内存里读取iPhone的价格,就会读取一个错误的价格 缓存一致性问题:1号核心和2号核心的缓存,此时是不一致的 同步机制能够达到的目标 写传播(Write Propagation) 在一个CPU核心里面的Cache数据更新,必须能够传播到其他对应节点的Cache Line里 事务串行化(Transaction Serialization) 在一个CPU核心里面的读取和写入,在其他节点看起来,顺序是一样的 事务串行化 1号核心先把iPhone的价格改成5000,差不多时间,2号核心把iPhone的价格改成6000,这两个修改会传播到3号核心和4号核心 3号核心先收到2号核心的写传播,再收到1号核心的写传播;4号核心刚好相反 虽然写传播做到了,...
计算机组成 -- 高速缓存
缓存行1234567$ sysctl -a | grep -E 'cacheline|cachesize'hw.cachesize: 17179869184 32768 262144 6291456 0 0 0 0 0 0hw.cachelinesize: 64 # 64 Byteshw.l1icachesize: 32768 # 32 KBhw.l1dcachesize: 32768 # 32 KBhw.l2cachesize: 262144 # 256 KBhw.l3cachesize: 6291456 # 6 MB 1234567891011121314151617181920212223242526public static void f1() { int[] arr = new int[64 * 1024 * 1024]; long start = System.currentTimeMillis(); for (int i = 0; i < arr.length; i++) { arr[i] *= 3; ...
计算机组成 -- 局部性原理
局部性原理 局部性原理:时间局部性(temporal locality)+空间局部性(spatial locality) 时间局部性:如果一个数据被访问了,在短时间内还会被再次访问 空间局部性:如果一个数据被访问了,和它相邻的数据也很快会被访问 亚马逊的商品假设:总共6亿商品,每件商品需要4MB的存储空间,总共需要2400TB的数据存储 存储成本 如果所有数据都放在内存里面,需要3600万美元 $3600 = \frac{2400TB}{1MB}×0.015$ 如果只在内存里存放前1%的热门商品,其余的放在HDD上,存储成本可以下降为45.6万美元,即原来成本的1.3% $45.5 ≈ 3600 \times 0.01+3600 \times 0.99 \times \frac{0.00004}{0.015}$ 时间局部性 时间局部性:LRU(Least Recently Used)缓存算法 热门商品被访问得多,就会始终被保存在内存里,而冷门商品被访问得少,就只存放在HDD硬盘上 越是热门的商品,越容易在内存中找到,能更好地利用内存的随机访问性能 假设日活为1亿,活跃用户每...
计算机组成 -- 存储层次结构
SRAM CPU类比成计算机的大脑;而正在思考的东西,可以类比成CPU中的寄存器(Register) 寄存器更像是CPU本身的一部分,存放极其有限的信息,但速度非常快,和CPU同步 大脑中的记忆,类比成CPU Cache(高速缓存) CPU Cache使用的芯片是SRAM(Static Random-Access Memory,静态随机存取存储器) 静态:只要处于通电状态,里面的数据就能保持存在,而一旦断电,里面的数据就会丢失 在SRAM里,1个比特的数据,需要6~8个晶体管 所以SRAM的存储密度不高,同样的物理空间下,能够存储的数据有限 SRAM的电路简单,所以访问速度非常快 在CPU里,通常会有L1、L2、L3这三层高速缓存 L1 Cache 每个CPU核心都有一块独占的L1 Cache,通常分为指令缓存和数据缓存 L1 Cache通常嵌在CPU核心的内部 L2 Cache L2 Cache同样是每个CPU核心都有,但往往不在CPU核心的内部,因此L2 Cache的访问速度会比L1 Cache稍慢 L3 Cache L3 Cache通常是多个CPU核心共用的,尺寸更大,访问速度...
计算机组成 -- 虚拟机
解释型虚拟机 要模拟一个计算机系统,最简单的办法,就是兼容这个计算机系统的指令集 开发一个应用程序,运行在操作系统上,该应用程序可以识别想要模拟的计算机系统的程序格式和指令,然后一条条去解释执行 原先的操作系统称为宿主机(Host),有能力模拟指令执行的软件称为模拟器(Emulator) 实际运行在模拟器上被虚拟出来的系统,称为客户机(Guest VM) 这种方式和运行Java程序的JVM比较类似,只不过JVM运行的是Java中间代码(字节码),而不是一个特定的计算机系统的指令 真实的应用案例:Android模拟器、游戏模拟器 优势 模拟的系统可以跨硬件 Android用的是ARM CPU,开发机用的是Intel X86 CPU,两边的CPU指令集是不一样的,但一样可以正常运行 劣势 无法做到精确模拟 很多老旧的硬件的程序运行,需要依赖特定的电路乃至电路特有的时钟频率,很难通过软件做到100%模拟 性能很差 并不是直接把指令交给CPU去执行,而是要经过各种解释和翻译的工作 编译优化:Java的JIT 把本来解释执行的指令,编译成Host可以直接运行的指令 全虚拟化 全...













