首先澄清一下 CPU占用100%是什么意思?
很多大大认为100% cpu占用就是cpu所有单元都在忙了,发挥最大效率了,实际上,100% 的cpu占用,只说明进程把这个cpu给霸满了,但CPU到底忙不忙,那是另外一回事。其实在99.999%的情况下,100%占用的cpu,都是将近一半的时间在等待,剩下一半的工作时间最多也只能用到2/3的运算单元,也就是说,即使是100% 的cpu占用,cpu其实最多也只有发挥了30%-40%的能力
那为什么会这样呢?
第一大CPU不能发挥的原因,就是缓冲区不命中导致的取指,数据的等待
众所周知,CPU的速度远远大于内存等外设,如果没有特别的措施,每执行一条指令,CPU都要等十几倍的时间从内存中取指令和数据,所以我们才设计了比内存快的多得一级,二级,甚至三级缓存来加速,但相对于256M 512M 1G 2G的内存16K的一级缓存和512K 或1M的2级缓存实在是太小了,最好情况是CPU直接在1级缓存中找到数据,这样会没有延迟,但只有16K的一级缓存往往是找不到的,这时就要到2级缓冲中寻找并填入1级缓冲中,这就会有3-5个甚至更多个周期的延迟,如果2级缓冲还找不到,这也是常有的事,CPU就会启动内存总线,开始缓冲区填充,把数据从内存中取回缓冲区。由于DDR,DDR2的潜伏期和相对的低频率,这个过程要十几二十几个周期
CPU运行时就是这样的受制与慢速内存,不断的等待
第二个CPU不能发挥的原因,是IO端口的存取
CPU操作硬盘等外设时,需要通过IO端口,DMA等存取比内存还慢的多得系统总线,虽然有中断和IO芯片的帮助,但这是比内存存取还糟10倍的情况,更糟的是在共享的总线上还常遇到冲突和总线等待的情况,对此大家用电脑时应该都有切身体会
第三个CPU不能发挥的原因,是不能充分并行和充分使用CPU执行单元
P4有5个整数单元,其中四个是双倍的,
所以P4有9个整数单元,2个浮点单元
Athlon 有6个整数单元,3个浮点单元
(其实看这个大家就应该知道,为什么I在媒体和商业程序超过A,A在spuer pi和一些game中超过I,CPU设计不同,没什么好吵的)
但A, I的CPU每时钟周期同时执行指令数的最大理论数是3,4条,远远小于执行单元数,这是因为一些复杂指令和sse, 3D now指令需要不止一个执行单元,但实际上CPU执行时95%的指令都是简单指令,于是我们就看到,绝大部分情况下,即使CPU以最大并行度运算,也只有4,5个执行单元在执行,其他的都在闲置
况且,更重要的是,CPU并不能以他的最大理论数同时执行指令。
我们的X86指令集和X86程序本质上都是单线设计的,一周期一操作,执行完上一条在执行下一条,其实本不能在一个周期里执行超过一条的指令,所以在现代CPU设计里,使用了很多技巧--乱序执行(在前后指令没有依存关系时同时执行他们),分值预测(在还没做条件判断是超前执行后面的指令)--等等来实现并行效果,但这些技术都是有局限的,所以虽然A, I的CPU每时钟周期同时执行指令数的最大理论数是3,4条,但实际上平均同时只有2条左右,cpu的执行单元大部分都是空闲的。
(这个情况直接根源于x86指令架构的落后,无论是IBM PPC的SIMD结构 还是Intel IA64的甚长指令架构都是真正的并行架构,实际上,除了X86,你在现在其他CPU里是找不到如此落后和古老的指令架构了,这是X86的辉煌还是悲哀呢)
除了以上三大原因,其他很多原因,包括操作系统进程切换,流水线清空,寄存器换名和重置等等很多原因都会造成CPU的浪费,他们虽比不上上面的三大原因,但加起来也是很大的数目
看到这里,大家就知道HT的原理了
HT使每周期同时执行指令数的最大理论数提高了一倍,在一个进程因为取指,数据的等待,IO操作...等等等待时,另一个进程可以乘机运行,同时,在一个进程不能充分并行和充分利用所有的执行单元时,另一个进程可以可以利用剩下的单元 |