正文
言归正传,这个特立独行的故事从这里开先,我们要认识一个老爷爷(还活着好像),他叫 Michael Flynn。老人家生于大萧条时代的扭腰城,一不小心提出了一个分类法,叫做 Flynn Taxonomy(1966)。然后计算机体系机构就被 Flynn taxonomy 的五指山给压几十年。
Flynn Taxonomy 的五指山把计算机结构分为两个部分:指令与数据,在时间轴上指令与数据可以单步执行或多次运行进行分类,即单指令单数据(SISD),单指令多数据(SIMD),多指令单数据(MISD)和多指令多数据(MIMD)。
并行,从 Pipeline 到 SIMD
Flynn taxonomy 给并行计算机体系结构指了两条明路——指令级并行和数据级并行。
首先来看下指令与数据的关系。指令是处理器单步可以实现的操作的集合。指令集里的每一条指令,都包含两个部分(1)什么操作,(2)对什么数据进行操作。专业地,我们把前者叫做 opcode,后者叫做 operand(也就是数据)。当然,并不是所有的命令都有数据操作。传统定义的指令集里面,对应的 operand 不超过 2。比如,加减乘除都是典型的二元操作。数据读写就是一元的,还有些就是没有任何数据的操作,比如一个条件判断(if)发生了,根据判断结果程序何去何从,只是一个 jump 操作,他并不需要任何数据输入。
你还记得(一)昨夜神风送层云里都提到的一个 neuron 计算么?每一个 neuron 都要经历 n 个输入的乘累加~
指令级并行的第一种、也是最经典的办法叫做时间上并行,这是所有的体系结构教科书最喜欢教的流水线架构(pipeline)。简而言之,在发明流水线以前,处理器里面只有一个老司机,什么事情都得他来干,但是下一条指令得等老司机干完上一个~但是,流水线就是把一个老死机变成了三个臭皮匠,每个人干三分之一就给下一个,这样下一条指令只需在上一条被干完 1/3 后就可以进来了。虽然老司机体力好,但赶不上年轻的臭皮匠干的快啊。这样,流水线可以实现时间上的指令集并行, 成倍提高实际指令的处理效率。
经典 MIPS-5 级流水线
有一就有二,有时间当然就有空间。所以,第二种办法是空间上的并行。空间并行基于一个观察——对数据的操作有很多种——加减乘除移位、整数操作、浮点操作……每一个模块的处理(ALU/EXU)是独立的,所以,就空间上,一个浮点加法在处理的时候,完全可以同时进行一个整数移位操作,像老顽童教小龙女的左右互搏分心二用。所以,在计算机体系的历史上,我们把练成「左右互博」术的处理器叫做——超标量(Superscalar)/超长指令 (Very Long Instruction Word, VLIW) 处理器。关键在于,有没有几套对应的前后 fetch /Decode /读写模块。在实际设计中,超标量从硬件层面进行自动对数据进行再排序,而 VLIW 是用编译器层面将 c-code 编译成更大条的指令。所以超标量的硬件更难做,而 VLIW 的编译器更难设计。