当前在线人数14449
首页 - 博客首页 - 大刀王五 - 文章阅读 [博客首页] [首页]
ZT X86是过时的结构?
作者:PBSNPR
发表时间:2018-06-25
更新时间:2018-06-25
浏览:133次
评论:0篇
地址:2601:18c:ce7f:be60:3.
::: 栏目 :::

作者:芦中人


回答这个问题先看个wiki,Instruction-level parallelism,x86曾经因为ilp,指令级的并行大有被mips操死在山顶的趋势,John Hennessy 和David Patterson 获得了今年的图灵奖,他们俩曾经写了一本影响了业界很多年的书,https://m.douban.com/book/subject/20452387/,也创建一间真正的公司实践自己的理论,risc核心基础并不在于指令集小,而在于所有指令定长,x86的指令集不是定长的,定长有什么好处,好处太tmd大了,因为等长的指令集可以很方便塞到流水线上,而我们平时用的寄存器r0, r1其实只是一个名字而已,事实上运算器和寄存器都可以有很多备份,给程序员看到的cpu 只是programmer interface, 而具体的implementations,只要符合指令集的约定就行了,所以没有因果关系的指令就可以并行执行,比如,我好久没写汇编了,汇编格式不一定对,而且各种汇编格式是那么个意思就好了。

1. load [1234] r0 #从地址1234取一个字
2. load [4567] r1 #从地址4567取一个字
3. add r0 r1 #把r0中的内容加上r1的内容保存在r0中。
4. save [1234] r0 #把r0 中的字存回地址1234
5. move r2 r0 #把r2一个字移动到r0
6. move r3 r1 #把r3一个字移动到r1
7. multi r0 r1 #r0和r1相乘保存结果在r0
8. move r0 r2 #把r0的结果移动回r2
9. move r6 r0 #把r6的数据移动到r0
10. move r7 r1 #把r7 的数据移动到r0
11. add r0 r1 #把r0和r1相加存在r0
12 move r0 r6 #把r0的结果存回r6

我们假设这12条指令,在这些指令中,最耗时的指令是1,2和4,对于cpu来说,在内存存取数据就是io,io的意思就是慢的一逼。这时候cpu的控制器会对这些指令进行重排,我们假设cpu一个机器周期是能执行完一个指令的,事实上一般不能,我们就假设能把。
我们第一个机器周期要执行的指令是

round 1:
1. load [1234] r0 #从地址1234取一个字
5. move r2 r0 #把r2一个字移动到r0
6. move r3 r1 #把r3一个字移动到r1
9. move r6 r0 #把r6的数据移动到r0
10. move r7 r1 #把r7 的数据移动到r0

事实上load内存的指令要可能需要几个到几十个机器周期,这里我们简化一下,我们假设一个机器周期能够执行完。也许你会纳闷我的1,5, 9都写了r0难道不会冲突吗?不会的,这就是现代超标量处理器的特征,不管运算器还是常规寄存器,都有很多备份,名字是一样的,你写的根本不是一个寄存器,或者叫register renaming。所以这些指令统统都是能够并行的,在一个周期一次性执行完毕收获结果,我之所以选择这样执行序列,只要是我分析了这些指令的因果关系,我把没有因果关系的指令统统能够并行,一个周期结束,我加载了1234地址的数据,然后分别把r0和r1都装进来了。

round 2
2. load [4567] r1 #从地址4567取一个字
7. multi r0 r1 #r0和r1相乘保存结果在r0
11. add r0 r1 #把r0和r1相加存在r0
round 3
3. add r0 r1 #把r0中的内容加上r1的内容保存在r0中。
8. move r0 r2 #把r0的结果移动回r2
12 move r0 r6 #把r0的结果存回r6
round 4
save [1234] r0 #把r0 中的字存回地址1234

为啥定长指令很屌,因为我preload指令的控制器加载一堆指令后会分析你这些指令的因果关系,然后算出执行序,也就是哪些指令和哪些指令可以一起发射,如果是不定长的话,妈蛋我拿第8个指令还需要知道前面7个是什么玩意,整个取指就是线性,非常恶心,而定长的可以一片一片加载进来分析因果关系,算下执行序,就开始干了。评论区有说了intel译码器其实是通过package往译码器队列里塞不定长指令的,而译码器是多路的,所以这里不会成为瓶颈.而且塞到流水线cisc处理的复杂度和不确定性指数级上升,因为指令数量,和一个指令的复杂程度和耦合程度,直接决定了你能不能在一个很小的空间做很多份运算单元,所以cisc指令天然难以超标量的。

事实上我上面的描述有点bug,我太简化了,一个周期好多时候执行不完这些发射在一起的指令的,所以有些指令是要执行好多周期的,比如从内存load save,可能最差要几十个周期。所以真正的流水线是好多层级并行的,而不是单条,每一个时钟周期,可能每个指令只进展一点点。具体参考计算机体系结构的书。所以这种RISC指令集是如此的屌,当年John Hennessy 和David Patterson开了mips公司,整出来屌炸天的超标量处理器是把cisc的英特尔和AMD操的一愣一愣的,完全只有拼命娇喘的份。但是,知耻而后勇,英特尔也不是甘心贡献菊花的货,他们凭借pc已经在有很多软件跑在他们的指令集上,然后巧妙的引进了一层抽象,使用risc的超标量ILP技术。

做法是我不改变x86变长指令集,我引入一个解码器,所以cisc指令集发射之前先吃进解码器,然后吐出来的就是定长的risc指令,好了吧,mips不屌了吧。所以凭借出色的销售能力和前期积累的客户,反过来把John Hennessy 和David Patterson操的一愣一愣的,后来John Hennessy 和David Patterson都回了大学当老师,MIPS卖来卖去,最后真沦落的像个妓女一样。英特尔和AMD屌大霸天。

所以什么是过时的结构,上层稳定傻逼程序员喜欢,底层抽象实现高效率,这才是最牛逼的架构。这就是cs领域抽象的胜利。具体实现独立于抽象。如果写一本处理器史记,感觉John Hennessy 和David Patterson都是可以记入世家的人,虽然他们的王国覆灭了,但是在处理器结构历史上,John Hennessy 和David Patterson绝壁是对现代处理器影响最深远的人,他们从学术界,亲自操刀杀入工业界,最后虽然失败了,让傻逼英特尔ARM捡了便宜,但是John Hennessy 和David Patterson的贡献非常巨大,所以最后获得图灵奖也是理所应当。

而其实英特尔的研发实力也不是弱鸡。别看龙芯那样要饭的那点钱,英特尔每年研发经费可能比整个中国半导体投入都要多,所以英特尔很多技术细节还是领先的。架构这东西,只要程序员喜欢,接口傻逼,又跑的快,谁关心具体细节。

总体来说,兼容和先占领市场才是王道,想当年江湖上的摩托罗拉去了天堂,施乐也去了天堂,mips虽然还在也等于没了,sun sparc 也没什么存在感了,到了oracle垃圾森手里只能死了,ibm那么牛逼让郭士纳大象跳舞整的也是江河日下,最后ppc也只是年年出来装逼了。当时很多处理器公司都去了天堂,最后结束战国,归于x86 arm。只是商业的胜利吧。



提示: 本博文来自于 CS 版

[上一篇] [下一篇] [发表评论] [写信问候] [收藏] [举报] 
 
暂无评论
 
用户名: 密码:
发表评论
评论:
[返回顶部] [刷新]  [给PBSNPR写信]  [大刀王五首页] [博客首页] [BBS 未名空间站]
 
Site Map - Contact Us - Terms and Conditions - Privacy Policy

版权所有BBS 未名空间站(mitbbs.com) since 1996