Conroe强在哪儿?Core vs K8架构解析
为使那些不熟悉处理器设计的读者也能理解文章后面的内容,我们首先从一个处理器微架构的速成教程开始。为了理解处理器设计的目标和优劣,你首先需要了解处理器执行的指令,所以我们从处理器运行的软件开始。
典型的 X86 程序的代码中大约有50%的指令是存储器访问指令,其中存储器读指令大约是存储器写指令的2倍。然后,大约15%到20%的指令是分支指令(if, then, else等)。剩余指令中,大部分是诸如“ADD”、“MUL”这样的较简单的计算指令。像“DIV”、“SQRT”这些较复杂的计算指令在所有指令中只占很少的一部分。所有这些指令都按照典型的流水线步骤执行:取指,解码,取操作数,执行,退出。
首先,处理器会根据指令指针寄存器(instruction pointer register)指示的地址取回指令。这时,对处理器来说,指令仅仅是一些没有意义的0、1字符串。只有在被解码之后,指令对处理器来说才开始有意义。指令被解码后可以得到操作数地址和操作码,而操作数地址可以在下一步发挥作用:取操作数。你不会希望处理器对操作数的地址进行计算,而是对那些地址里面存放的内容进行计算——与 C 语言里面的指针的概念很相似。当操作数被取出来以后,ALU根据操作码的指示,就可以对操作数进行正确的计算了。计算结果一般将被写回处理器内部的寄存器堆中。有时候,计算结果也需要写回到缓存和内存中。这就是最后的步骤——退出。到此为止,你应该略微了解一条指令的整个执行过程了。
今天,对处理器设计者来说,主要的挑战是处理器的存储器访问平均延迟。在一个由 Pentium 4 3.6GHz 和 DDR400 内存构成的系统中,处理器的速度是内存的速度(200MHz)的18倍。也就是说,访问内存的每一个周期,处理器会经过18个周期。而且,发送一个内存访问请求需要多个内存周期,回应一个内存访问也需要多个周期。因此,对于 Pentium 4 来说,花费200到300个处理器周期来等待内存访问的完成并不罕见。设计处理器缓存的目标就是避免内存访问的发生。但即使处理器缓存的缺失率仅为4%,也就是说,在处理器访问存储器的所有情况中只有4%的比例需要访问内存,这4%也将显著降低处理器的执行效率。