研究指令并行优化,对这几个概念,一直不是很清楚,经过多方查找,应该差不多了。
流水线:指令执行过程分为多个阶段,每个阶段需要的资源不一样,因此可以采用流水线技术,同时执行多条指令的不同阶段。如可以将指令周期简单分为取指令和执行指令,取指令由取指部件完成,执行指令由执行部件完成,如果采用串行化执行,则在执行指令1时,取指部件是空闲的,执行取指2时,执行部件是空闲的,这不是浪费吗?
于是便有聪明人提出流水线执行,一条指令的执行过程分成2级,让每个部件都动起来。
![流水线 超标量 超线程 多核-LMLPHP 流水线 超标量 超线程 多核-LMLPHP](https://c1.lmlphp.com/user/master/2020/11/13/4597281a9ab8ea9ec8579ec9ee2b827e.png)
像这样执行,就可以就可以高效利用每个部件,只要有活就不怕你闲着。程序中的指令依旧还是一条条顺序执行,但是我让每个部件都动起来,就如同流水线的工人一样,你做你的工序,我做我的工序,做完都直接丢下家。如果每条指令分配给六个不同的部件,理想情况下从第六个时间段开始,每一个时间段都会有执行完的指令。流水线技术并没有减少每一条指令执行时间,但是在流水线满以后,如果一条指令用时6s,平均分成6部分以后,那就可以每1s得到一个执行结果。
![流水线 超标量 超线程 多核-LMLPHP 流水线 超标量 超线程 多核-LMLPHP](https://c1.lmlphp.com/user/master/2020/11/13/5c772ba2af6d33e39905725da697e6cb.png)
intel首次在1989 年推出的 i486 处理器引入了五级(也有人说六级)流水线。这时,在 CPU 中不再仅运行一条指令,每一级流水线在同一时刻都运行着不同的指令。这个设计使得 i486 比同频率的 386 处理器性能提升了不止一倍。
超级流水线:这个简单,就是把每一条指令细分成很多级。让每一级的执行时间减少。这样效率就更高了。这里参考网上的一段描述,个人认为比较好理解:
我们先对流水线的级数与其周期的关系给出一个公式,一个k级流水线,处理n个任务总共需要花费“k+(n-1)”个周期,这是因为先是处理第一个任务就需要k个时钟周期,k个周期后流水线被装满,剩余n-1个任务只需n-1个周期就能完成。如果同样数量的n个任务不采用流水线处理,那么就需要n*k个周期。
下面我们举例说明这个问题。首先定义完成某任务需要20s,K定义为5级流水线,则每一级需要时间周期为4s。要完成的任务数n为10.这样完成这10个任务,需要的时间为20+(10-1)×4 = 56s。现在我们把k级流水线改进成10级,这样每一级需要的时间周期就变成2s,同样完成10个任务所需奥的时间就是:20+(10-1)×2=38s,也就是说分的级数越多,需要的时间越少,那也就是说执行数度越快。这就是超级流水线的本意。网络的资源就是多,定义“超流水线技术”是在一个时钟周期内在分段,让一个功能部分被重叠使用多次。可能不太好理解,我也理解不动,总之理解为把级数分得多,应该没错。
超标量流水线:超标量(superscalar)是指在CPU中有一条以上的流水线,并且每时钟周期内可以完成一条以上的指令,这种设计就叫超标量技术。 其实质是以空间换取时间。支持超标量的cpu支持指令级并行,每个周期可以发射多条指令(2-4条居多)。简单如下图:
超线程 多核:上面所说的其实都是事物发展过程史的一小段,进化到现在到了多核的地步。目的一直没变,就是cpu频率提升到头,纵向已经没啥前途,转而进行横向发展。单核速度提升不了,那就并行。
其它:指令级并行方面,需要硬件和软件技术互相配合,通过各种技术手段,最大限度地挖掘出程序中存在的指令级并行。在cpu硬件设计方面、编译器方面、编程用户方面都可以做一些事。
硬件设计:除了设计多发射,超标量,多核。还有流水线分支预测技术,乱序执行,数据重定向,各种预测缓存,各种令牌记录
编程人员:
1 尽量减少代码中的跳转,你不经意的一个if-else可能带来的后果非常出乎你的预料。
2 代码中的循环具有潜在的指令级并行。指令展开。
3 减少数据相关性
4 减少指令相关性
5 用好simd
编译器:大部分编译器的功效都依赖于硬件,并且受用户代码制约
1 指令调度,寄存器重命名
任重道远啊,同志们!!!