图形渲染流程
-
顶点处理
每个多边形都有多个顶点 而这每个顶点都是在一个三维空间的坐标,但是屏幕是二维的,所以在确定当前视角的时候,需要把三位坐标系里的坐标转换到二维坐标系中,这个过程就叫做顶点处理。在3D建模的时候 建模越精细 需要的计算就越大 那么这些顶点的计算之间没有相互依赖 所以可以并行执行 -
图元处理
其实就是把顶点处理的各个点链接起来,还要把不在屏幕中的坐标删除,减少下一层的计算量 -
栅格化
把图元处理后的多边形转化成屏幕里的一个个像素点,可以并行处理 -
片段处理
在栅格化变成像素点之后,图像还是黑白的 还需要计算每一个像素的颜色 透明度等信息,给像素点上色。 -
像素操作
把不同的多边形的像素点混合到一起,前后的颜色要混合到一起变成一个新颜色,或者前边的挡住了后边的多边形。
以上是图像流水线。
GPU
GPU不需要有CPU那么复杂的功能 他只用按照一个指定好的顺序执行就好
-
芯片瘦身 只留下取指令 指令译码 ALU 执行上下文 不需要分支预测 乱序执行 这样就简单了
-
多核并行 和 SIMT
多核:可以在GPU里塞很多并行的GPU电路,像多核CPU一样
SIMT:可以把多条数据交给不同的线程去处理
- GPU里的超线程技术
在CPU中 超线程是在当前流水线停顿的时候 调度一些别的任务给到当前的ALU
GPU也是一样
- 通用着色架构 使得GPU变成了一个有通用计算能力的架构
存储架构
一、寄存器
CPU中的一部分 速度和CPU同步 PC寄存器 指令寄存器
二、CPU中的 SARM 静态存储器
L1 L2 L3 每个CPU核心都有一个自己的L1 高速缓存 ,分为指令缓存和数据缓存 L2也是每个核心都有的 不过不在CPU内部 速度稍慢 L3是多个CPU公用的部分 速度更慢 尺寸更大
三、DRAM 内存芯片 动态存储器
一个比特 只需要一个晶体管和一个电容 DRAM在同样的物理空间下,能够存储的数据更多,因为数据是存在电容里的,电容会不断漏电,所以需要定时刷新充电,才能保证数据不丢失
四、存储的层次结构
regs-L1 cache-L2-L3-Memeory-SSD-HDD 容量越来越大 速度越来越慢 价格越来越低
存储器只能和他相临的一层存储器打交道
五、CPU的数据结构和读取过程
-
读取过程
无论数据在不在缓存中 都会先读缓存 如果缓存命中就会直接读缓存,如果不命中就会读内存 然后把数据放在高速缓存中。 -
数据结构-直接映射Cache
CPU读内存数据是一块一块读的,直接映射Cache的策略就是确保内存块的地址始终映射到一个固定的CPU Cache地址(Cache line)。使用mod 取余运算来实现的
例如一个被分成0-31号这样的32个块的主内存 共有8个缓存块,用户想访问21号内存块对应的缓存块 就是 21 mod 8 = 5 也就是在第5号 Cache line中
- 组标记
在上边的例子中 13号内存 5号内存都会缓存到 5号CPU缓存中那么如何确定拿到5号CPU缓存是对应的内存条里的那一段呢?此时就要加上组标记
- 对于21来讲 10101 101 代表的是存储在5号CPU缓存 10 就是组标记
- 有效位 标示数据是否有效
- 数据
内存地址对应到Cache里的数据最终变成 索引 + 有效位 + 组标记 + 数据
如果内存中的数据已经在CPU cache中 内存地址的访问会经历如下步骤
- 根据内存地址的低位 计算cache中的索引
- 判断有效位 确认cache中的数据是有效的
- 对比内存访问地址的高位和Cache中的组标记,确认Cache中的数据就是我们要访问的内存数据,从Cache Line中读取到对应的数据块
- 根据内存地址的Offset 从Data Block 中 读取希望读取的字
CPU高速缓存的写入
CPU Cache写入方式
一、写直达
首先判断数据是否在CPU Cache中 如果在就更新缓存 再更新到主内存,如果不在就直接更新内存。
以上方案的问题就是每次都要处理内存 速度会慢
二、写回
这种方案不用每次都把数据写入到主内存,而是只写到CPU Cache里,只有当CPU Cache里面的数据要被替换的时候,才把数据写入到主内存里去。具体步骤如下:
内存数据写入
- 缓存命中 说明原有数据已经在缓存中 这是直接更新CPU Cache Block 并且将缓存块标记成脏的,脏的就是当前的数据和主内存中的数据不一致
- 缓存不命中 定位到缓存应该在的缓存块 如果当前缓存块的数据是脏的 那么此时这个缓存块中就是存储的别的数据 此时需要将缓存块中的数据写入到主内存,再把当前要写入的数据写入到Cache里,同时把Cache Block标记成脏的。如果Block里的数据不是脏的,那么我们直接把数据写入Cache里 并且标记成脏的就好了。
- 标记成脏的的原因是 当缓存不命中 并且缓存块存储的是别的数据的时候 可以把数据同步到主内存中。
多核CPU 保证缓存的一致性
所谓的缓存一致性 就是说 假设我们有2个CPU核 每个CPU核心都有L1 L2Cache 这时如果其中一个CPU核心修改了数据 只是采用写回的策略把数据写入到L1或者L2缓存中 并没有同步到L3或者主内存中 那么这是另外一个CPU核心读到数据就是错误的。
解决缓存一致性问题 需要亮点
一、写传播
在一个CPU核心 Cache数据的更新 必须能够传播到其他的对应节点的Cache Line里。
二、事务串行化
在一个CPU核心里读取个写入的顺序在其他节点看起来顺序是一样的
- 一个CPU核心对于数据的操作需要同步给其他CPU核心。
- 有一个锁的概念 只有拿到了锁之后才能对数据进行更新。
三、总线嗅探机制和MESI 协议
- 总线嗅探机制
很简单就是CPU中修改的内容通过总线通知到其他所有的CPU - MESI 协议 是一种写失效的协议
M:已修改
E:独占
S:共享
I:已失效