计算机底层原理
- 并行范式转移
- 现在的计算机及游戏机都包含多个并行运行的CPU核心,
- 开发软件时也要利用这些并行能力,往并行处理的范式转移
- 现今的CPU都是流水线(pipeline)的,这是指可以同时执行多个指令
- 现在的GPU也是大规模并行计算引擎,可同时并行处理数百以至数千个运算
- CPU性能的提升速度高于内存访问的提升速度
- 在CPU上做更多工作,去避免访问内存
- 内存缓存
- 访问现代游戏或者PC的主系统内存是缓慢的操作,通常需要几千个处理周期才能完成
- 和CPU里的寄存器相比,存取寄存器只需要数十个周期,甚至有时只需要一个周期
- 为了降低读写主内存的平均时间,现在的处理器会采用高速的内存缓存
- CPU读写缓存的速度比读写主内存快的多
- 缓存内存通常采用现存最快(及最贵的)技术
- 缓存内存在物理上尽量置于最接近CPU核心的地方,通常置于同一芯片上
- 缓存内存通常比主内存的容量小
- 内存缓存系统提升内存访问性能的方法是——将程序最常使用的数据块保存至缓存的局部拷贝
- 若CPU请求的数据已经存在于缓存中,缓存就能非常快速的完成请求(缓存命中)
- 若数据未置于缓存中,那么必须从主内存读入缓存(缓存命中失败)
- 缓存线
- 为了减低缓存命中失败的冲击,缓存控制器会尝试载入多于所请求的内存
- 理念:若程序顺序访问内存,那么首次访问时会导致缓存命中失败的开销,但是之后的访问就是低开销的缓存命中
- 缓存的内存地址和主内存的地址为一个简单一对多关系
- 缓存的地址空间以一个重复的模式被映射至主内存地址
- 缓存只能处理与缓存线大小倍数对齐的内存地址
- 缓存实际上只能以缓存线为单位寻址,而非以字节为单位
- 指令缓存和数据缓存
- 指令缓存会预载即将执行的机器码
- 数据缓存则用来加速从主内存读写数据
- 大多数处理器会在物理上独立分开这两种缓存
- 组关联和替换策略
- 缓存线与主内存地址之间的简单映射为直接映射缓存
- 主存中每个地址仅映射至单条缓存线
- 当发生缓存命中失败时,CPU必须把对应的缓存线从主存载入缓存
- 若该缓存线无合法数据,那么只需要拷贝数据进去就好了
- 若该缓存线已包含数据(来自来自另一内存块),我们必须覆写它(逐出数据)
- 直接映射缓存存在问题:
- 两个不相关的内存块可能不断来回相互逐出
- 解决:主内存地址能映射至两个或者更多的不同缓存线,就能获取更好的平均性能
- 当缓存命中失败:
- 逐出最老的数据(CPU替换策略)
- 写入策略
- 透写式缓存
- 写入缓存,会立即把数据同时写入主内存
- 回写式
- 数据会先写到缓存中,在某些情况下才会把缓存线会写到主内存
- 情况1:一条曾写过新数据的缓存线需要不被逐出缓存,以供主内存载入新的缓存线
- 情况2:程序明确要清除缓存
- 数据会先写到缓存中,在某些情况下才会把缓存线会写到主内存
- 透写式缓存
- 多级缓存
- 缓存越大,命中率越高
- 缓存越大,越慢
- CPU先尝试在一级缓存中找数据,
- 缓存小,但是有非常低的访问延迟
- 若数据不在,就尝试更大但是更慢的二级缓存
- 数据再找不到的时候,支付访问主内存的成本
- 缓存一致性:mesi和moesi