试着总结ILP有关的瓶颈与技术,有些可能不仅局限于ILP。
感觉写的很烂,所以求大佬指点。qvq
ILP有关因素
程序(hardware):
- 处理器内部工作频率(主频),指令周期大小
- 程序指令数,程序执行时间(程序开始到结束所花时间)
- 取指取数的频率和延迟
- 处理器每周期发射/提交的指令数
- 上下文相关性(如流水线冒险与数据相关)
- 指令译码
- 调度开销(如中断导致的调度等)
- 出于安全性导致的额外开销或保守性的优化
流水线冒险与上下文相关:
- 结构冒险(流水化后,硬件无法在同一时间应对所有操作)
- 数据冒险(写后读RAW,读后写WAR,写后写WAW)
- 控制冒险(分支指令及其它改变程序计数器的指令实现流水化时可能导致)
- 数据相关
- 名称相关
- 控制相关
存储器:
- 存储墙memory wall
- 存储器的频率,带宽,延迟,容量
- 缺失率,缺失代价
- 存储器中的上下文相关
程序(software):
- 程序的设计水平
- 程序指令数
- 上下文相关性
- 异常问题
- 一致性问题
- 调度开销(如陷入内核等)
- 程序管理开销(如内核需要对程序映射空间进行管理)
- 出于安全性导致的额外开销或保守性的优化
I/O与设备:
- I/O频率与带宽
- I/O延迟
- I/O性能与设备性能(程序可能浪费大量时间在等待设备运行完成的答应上)
- 设备中断开销
改善ILP的技术
指令体系结构:
- 合理精简指令体系结构以减少硬件实现上的麻烦(如RISC设计思想)
- 合理增加指令体系结构功能以减少软件实现上的麻烦(如拓展指令集)
- 提供足够的通用寄存器(主要是为编译器服务)
- 利用局域性原理(一般认为一个程序90%的执行时间花在10%的代码中)
- 超长指令字VLIW
- 与内核程序协作(设计时考虑内核需求)
- 与编译器协作(如由编译器指出冒险与冲突Itanium,设计时应该考虑到编译器的存在)
- 针对特殊场景需求设计(特殊化的体系结构)
软件层:
- 如循环展开,静态调度,甚至硬件相关的软件优化,看编译原理
执行流技术:
- 预取技术prefetch
- 流水线技术pipline
- 动态调度技术dynamic scheduling
- 乱序执行技术out of order
- 推测执行技术prediction(主要是分支预测branch prediction)
- 超标量superscale
- 多发射技术multiple issue
- 宏融合技术macro-fusion
程序调度:
- 重叠窗口技术overlapping register windows
- 减少权态切换频率及开销(如内核线程,轻量级线程,用户线程的概念)
- 在体系结构上尽可能提供相关支持
冒险和数据相关:
- 记分牌算法scoreboard
- 延迟槽delay slot
- 旁路转发forwarding
- 寄存器重命名renaming
- 重排序缓冲区reorder buffer
- tomasulo算法
存储器:
- 构建存储器体系以应对存储墙
- 利用局域性原理(如cache)
- 使用快表TLB(translation lookaside buffer)
- 各种cache优化技术,见隔壁(点我这里)
I/O瓶颈:
- 减少设备中断次数
- 减少设备中断程序时间(如在设备上集成微处理器以自行处理更多事务)
- 减少中断切换次数(如将多个中断一并处理,而无需反复切换权态)
- 减少陷入中断开销
- 设备虚拟化
挖掘其它的并行性,而不是死磕ILP:
- 线程级并行TLP(利用线程调度填充硬件的空闲)
- 请求级并行RLP
- 数据级并行DLP(如向量处理器)
- 单指令流多线程流SIMT(如GPGPU)
其他方面的改进(目前的主要因素):
- 更好的工艺
- 更先进的封装技术
- 更好的主板
- 更好的散热与物理环境(功耗墙power wall!)
- 功耗改善的设计
- 利用协处理器(如显卡)
更多的ILP技术
//这些技术更加激进,而不一定适用于一般的体系结构设计中。
- 处理访问存储器时的WAW/WAR冒险
- 减少更多不必要的相关(例如,完全展开某个for循环)
- 预测数据(例如,预测程序将从存储器读取什么数值)
- trace processor或trace cache