程序员需要了解的底层知识
概要
本文主要归纳和整理程序设计开发中需要了解和使用到的底层硬件和操作系统相关知识,操作系统以Linux为参考
计算机组成
CPU
1.缓存一致性
当CPU向内存写入数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存行是无效的,那么它就会从内存重新读取
2.缓存对齐
由于CPU缓存与内存速度之间的差距,为了提高效率,数据按一定大小的行从内存加载到CPU缓存,目前多为64个字节,对于一些关键数据,存在线程高竞争访问,为了防止数据共享,采取填充数据的方式,使数据刚好组成一个缓存行
3.乱序执行
指CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理的技术
4.合并写
由于ALU速度太快,所以在写入L1的同时,写入一个WC Buffer,满了之后,再直接更新到L2
内存
1.内存分页管理
为了提高内存的使用率,解决内存不够问题,程序的数据不是一次性加载到内存,而是才用分页方式,按需加载,当内存不够,采用LRU算法进行内存交换
2.虚拟内存
在多任务情况下,为了防止进程之间的相互干扰,程序采用虚拟地址空间,通过软硬结合方式进行寻址
3.缺页中断
当内存中没有需要的数据页,将产生缺页中断,由内核处理加载
IO
核心概念
VFS(虚拟文件系统)
计算机存在各种各样的IO设备,不同的文件系统,为了为应用程序提供统一的操作接口,在Unix/Linux系统中,通过VFS,把不同的物理文件系统、IO设备抽象为一颗目录树,把它们统一当文件对待(一切皆文件)。VFS存在于内存中,系统启动时创建,系统关闭时销毁。
FD(文件描述符)
内核为每个进程维护的该进程打开文件记录表的索引值,每个进程都有的文件描述符为:0-标准输入、1-标准输出、2-标准错误
磁盘IO
Page Cache——由于磁盘的读写速度较慢,而内存的读写速度较快,通过Page Cache将磁盘的多块数据缓存到内存中,减少IO次数,提高性能。Page Cache一般为4KB大小
- 读Cache
当应用程序发起读请求时,如果读取内容在缓存中命中,则直接读取,否则会产生缺页中断 - 写Cache
当应用程序发起写请求时,内核会把内容写入缓存,同时把其标注为dirty,然后根据同步设置刷入到磁盘 - Cache回收
当内存不够时,这时一般会采用LRU算法,释放掉一部分Cache
网络IO
TCP三次握手
当计算机A和计算机B通过TCP协议三次握手后,各自会为此连接分配资源,并且通过A的ip和端口号加上B的ip和端口号唯一标识,三次握手建立连接过程是在内核完成,不需要应用程序参与。连接建立后应用程序通过accept系统调用,建立内核资源与应用之间的绑定,返回文件描述符,参见下图:
- backlog参数——用于描述已建立连接但是未被accept的队列长度,当队列满之后,新进连接请求将进入半连接队列(SYN_REVD队列),当半连接队列满之后,新的连接请求将被丢弃
- 内核为每个连接分配指定大小的缓存,用于接收数据,当缓存满了之后,新的数据将堆积在客户端,如果客户端缓存满了,客户端写数据将被阻塞
如下图,三次握手完成后,能够知道服务端所能接收的数据大小为1152
当服务端接收完1152个字节的数据后,服务端会告诉客户端不要在发送数据(win 0),这时客户端所有发送数据将堆积在客户端
####TCP四次分手