首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 问一个关于CPU指令执行的问题--乱序执行 [已结贴,结贴人:youqika]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 19:01:58 楼主
    最近听说为了使CPU被高效的利用,引入了乱序引擎.
    这样即使是汇编级也不知道下一步会执行什么指令,
    问题是程序员如何调试呢?
    乱序会使程序执行出错吗?还是对程序员透明(即我们
    仍然可以认为它是按我们设计(假设我用汇编)的那样
    顺序执行,即使实际上是乱序执行的)?
    50  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 19:03:081楼 得分:0
    这是在说并发吧?
    在转到另一个程序的时候保存现场,回来的时候恢复...
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 19:15:062楼 得分:0
    这个是 cpu内部的东西,和写的程序没有关系了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 19:25:243楼 得分:0
    乱序会使程序执行出错吗?
    乱序会使程序达不到你的要求,我想你说的应该是关于多线程的程序吧。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • WingForce
    • 等级:
    发表于:2008-05-06 20:01:524楼 得分:0
    乱序执行对程序员透明
    乱序执行是现代cpu使用的一种技术,用以提高cpu的利用率。
    一个不恰当的比方:
    要做一个项目,有几个架构师,几个程序员,几个市场人员等等,大家分工不同
    项目来的时候,如果一个一个步骤走下去,先市场,架构,在到程序员,比较慢
    于是,有个天才的领导,随意的把项目的各个步骤先分发给每个人。
    架构师先根据已知的一些信息进行架构设计
    程序员开始部分编码
    市场人员跟进客户
    在执行了一段时间后,领导把大家的工作成果汇总,结果发现,很巧合的,虽然大部分程序员设计的代码和大部分架构师设计的系统不稳和
    市场人员的调研结果也和设计大部分不吻合,但是总有一小部分是可以整合在一起的,这样就小小的节省了一点时间
    介个就叫做乱序执行,呵呵
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 20:53:245楼 得分:0
    建议楼主看一下计算机系统结构
    就明白了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 21:06:586楼 得分:10
    在调试模式下,程序是没有优化过的,不会启动编译器的指令重排优化,也不会启动CPU的指令乱序执行。
    指令乱序执行和编译器的重排优化对调试是没有影响的。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • redleaves
    • 等级:
    发表于:2008-05-06 21:07:527楼 得分:5
    虽然执行的时候不按顺序,但结果还是顺序的。而且只有上下文无关的内容才能这么执行。在宏观(汇编级)上,还是顺序的。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 21:09:388楼 得分:0
    另外,乱序执行对于执行结果是不会有影响的。
    只有在指令之间没有相互依赖的情况下才会使用乱序执行。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-06 21:17:499楼 得分:0
    mark
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • sjjf
    • 等级:
    发表于:2008-05-06 21:57:1610楼 得分:0
    理解了拓扑排序,也就理解了乱序的缘由,
    乱序是为了克服流水线因跳转等导致的中断的带来的效率缺陷而采用的一种技术
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 12:08:5811楼 得分:0
    请大家不要为了拿分答非所问,4楼的和10楼的注意了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 12:41:0312楼 得分:0
    我也想知道这个哦~
    不知道怎么回事我得电脑经常也出问题哈
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 12:48:1313楼 得分:10
    乱序跟多线程不是一个概念,也没有直接关系。
    对于楼主的问题,至少在你单步跟踪的时候,debugger是不会把语句会乱序的。这点可以放心。
    另外,乱序技术的大前提是不影响程序正确性,也就是要在保证结果正确的前提下提高效率。这点也可以放心。
    至于其它的,如果没有研究的兴趣,就先放一放吧;如果有兴趣,可以看看计算机体系结构方面的书。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 12:51:4514楼 得分:0
    今天看了《计算机组成(结构化方法第5版)》,
    里面也介绍了一些,不过13楼的让我放心多了,谢谢,加分
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 12:57:1215楼 得分:0
    也就是说对程序员编程没有影响吧,即使是汇编程序员?
    1:int x=0,z;
    2:x=1;
    3:if(x>0)
    4:    z=10/x;
    如果第4行比第2行先执行或者说先执行完毕,
    处理器会陷入异常,那怎么处理呢?
    这会让程序员不知所措吧,明明是正确的程序啊!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 12:59:4216楼 得分:5
    其实乱序执行一直都有,流水线就是这个原理。
    这次这个“乱序引擎”给我的感觉就是把流水线加得更深了,CPU有更多硬件资源可以用,更多的没有相关性的指令可以被同时执行。
    这些对高级程序员来说都是透明的,指令执行顺序是由编译器确定的,CPU是在保证指令执行结果正确的情况下,同时执行多条指令。
    所以程序员完全没必要担心。

    但汇编级编程还是可以人工干预指令执行顺序以获得更快的执行速度
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 13:00:4917楼 得分:0
    13楼的是说处理器在调试模式时是顺序执行的,
    丝毫没有乱序吗?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • redleaves
    • 等级:
    发表于:2008-05-07 13:30:4818楼 得分:10
    指令重排通常是在不影响程序逻辑的情况下,由编译器(通常是这样的)将生成的机器指令,按照流水线的特点,重新排列,以达到更高的流水线填充率,从而提高程序速度的机制.通常,高级优化编译出的结果就是经过重排的,所以RELEASE版程序在调试时,你会发现经常下不准断点.
    而乱序执行通常是指CPU的一种硬件机制,它不改变宏观上的执行过程(指令的排列),只是在指令发射时,根据当时的分枝状况,及代码相关性,优先执行一些不相关的但在排列在后面指令的机制.这是CPU硬件层次的东西,对上层的应用是透明的,用户无法直接感觉到它的存在.(如果让用户发现了,那结果就可能有错了)
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 13:38:2719楼 得分:10
    老大,多看看书吧!

    乱序执行是有条件的,不是真乱:

    1:    int x=0,z; 
    2:    x=1; 
    3:    y=2;
    4:    if(x>0) z=10/x; 
    5:    y=y+x+z;

    上面的代码,在顺序cpu上,绝对可以保证第2句在第3句前完成。
    但是在乱序CPU上,不可能有人知道第2句和第3句究竟谁先完成。因为你把第2、3句反过来写程序的执行结果也不会有丝毫改变。你能做的事CPU也能做。

    可以保证的是:第5句一定是最后才执行,因为他所需的变量值必须等前面3句执行完才可以确定。

    有一点可能性的是:
    在顺序cpu上第一句(x=0)会被执行。而在乱序CPU上,第一句可能不会被执行,因为x的连续两次赋值之间,它的值没有被别人取用,所以第一次赋值的操作可以抛弃,从而减少了一次无用的运算。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 13:57:0120楼 得分:0
    多谢大家帮助,结帖!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 14:04:4921楼 得分:0
    对程序员透明是透明的不必关心。。。。
    你会汇编语言就不会问这问题了。。。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ttlyfast
    • 等级:
    发表于:2008-05-07 14:59:0022楼 得分:0
    引用 5 楼 simo110 的回复:
    建议楼主看一下计算机系统结构 
    就明白了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ttlyfast
    • 等级:
    发表于:2008-05-07 15:02:1223楼 得分:0
    一般...弄清楚资源的依赖关系9行了
    可以根据硬件结构来重新组织语句的顺序,以达到优化程序的目的 :-D
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 16:49:3424楼 得分:0
    没听说过什么乱序,但自从CPU引入了流水线技术之后,指令执行就不是顺序的,而是跳跃的,因为CPU预取指令可能是1条,也可能是2条,所以你要经过计算才能知道,下一条指令的地址在哪里。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 16:50:3825楼 得分:0
    当然你在汇编级处理时,必须考虑流水线的取指令技术,要不然就会计算错误下一条指令的地址。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 17:11:1126楼 得分:0
    基础知识,计算机系的基础课程,找本计算机体系结构的教材看看吧
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • bjsun
    • 等级:
    发表于:2008-05-08 09:05:1527楼 得分:0
    该回复于2008-05-09 09:44:19被管理员删除
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 09:16:2328楼 得分:0
    记得CPU很早就可以乱序执行了,我觉得从奔腾2开始就已经乱序了,也可能更早。
    这跟程序员没关系,这是CPU内部电路的事.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 09:39:1729楼 得分:0
    看到学习了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:19:3530楼 得分:0
    我比较同意楼的观点,乱序应该在调试的时候,不能妨害调试器的运行。其实我一直也有疑问,流水线的一些东西,在调试的时候,如何处理呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 11:19:5131楼 得分:0
    谢谢大家踊跃发言!!!
    最后还是我自己做个了结吧,看了些资料,自己的理解,不一定完全正确

    先从指令预取讲起,至于为什么要预取,就不废话了
    CPU使用pipeline实现指令预取,就是缓存啦,将准备执行的指令
    预取到缓存中,如果指令本身要访问内存数据元素,也从内存中读取
    并写入缓存,但一级缓存还不够好,如果程序采用了逻辑分支,使指令
    转移到内存中完全不同的位置,那整个缓存就没用了,所有的缓存指令
    将被新的预取指令覆盖而产生新的缓存指令,如果这时又要跳回去呢?
    缓存的又没用了,CPU又要等待,因而出现了二级(多级)缓存(/*不知道可对,
    个人认是下一级缓存在上一级被清空时备份上一级的缓存*/)
    ,它保存了原来一级缓存中的指令,这样跳回去时也不用到内存取指令.

    乱序执行引擎是在CPU的控制单元中的,它包含几个缓冲区用于改变pipeline中
    的指令的顺序,以便提高控制单元的性能.它将缓存的指令分析然后重新排序,找出
    那些能够独立(不需要前面指令的执行结果,前面的指令执行与否对它的执行及结果没影响)
    执行的指令送入执行单元(之前还要分解为微操作)并发执行,而真正当EIP指向某条指令时,
    它可能已经被执行过了,那CPU仅仅返回正确的结果而已(这个过程用到了寄存器重命名的技术),不会再执行一次
    /*举个简单的例子,不一定恰当
        mov eax,0xFFFF    ;乱序执行引擎中包含128(假设时R0~R127)个逻辑寄存器,程序员无法操纵
                             ;这条指令可能被分析为时独立的指令,将它变成mov R0,0xFFFF(就是将R0与eax这个名字绑定)
                          ;然后执行,而真正当EIP指向这条指令时,仅仅是将R0复制到eax中,只是我们好象以为是真的刚刚
                             ;才执行这条指令,这样我们编程仍然可以想象成CPU是一条汇编一条汇编的向下执行,效果一样,
                          ;也就对程序员透明了
    */

    以上是我个人的理解,不知道可对,大家看看指正,谢谢!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 13:51:0832楼 得分:0
    乱序执行,分支预测,都不是什么新东西了。
    我建议你看斯坦福大学校长 John L.Hennessy 《计算机体系结构:量化研究方法》。我们当年上课的教材。有好几章讲这个,以及CPU内部如何实现乱序。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 13:56:5833楼 得分:0
    我建议你要把Data Cache和Instruction Cache分清楚。
    还要把流水线和cache分清楚。
    当流水线中的指令出现分支指令时,流水线要排空。不是cache排空。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 14:13:5034楼 得分:0
    引用 32 楼 codewarrior 的回复:
    乱序执行,分支预测,都不是什么新东西了。
    我建议你看斯坦福大学校长 John L.Hennessy 《计算机体系结构:量化研究方法》。我们当年上课的教材。有好几章讲这个,以及CPU内部如何实现乱序。

    问这位仁兄,有没有这本书的CHM版或者PDF清晰版,拿出来大家看看啊.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-08 15:06:4035楼 得分:0
    你这个帖子,我一定要收藏一下,非常不错
    修改 删除 举报 引用 回复
    进入用户个人空间