条件分支的两种方式的对比——条件控制与条件数据

1.条件码
前提:在机器代码中,寄存器里有一组单个字的条件码寄存器,他们描述了最近的算术或逻辑操作的属性。可以检测这些寄存器来执行条件分支指令。常见的条件码如下:
条件分支的两种方式的对比——条件控制与条件数据 - 中山爷爷 - 凝聚 的博客
但是,条件码是不能直接访问的,常用的方式有三种:
1. )可以根据条件码的某种组合, 将一个字节设置为0或者1;
2.)可以条件跳转到程序的某个其他的部分;
3.) 可以有条件地 传送数据
 2.跳转指令
机器代码里面的跳转指令类似于C语言的goto,能够跳转至label处的代码执行。因此,IF,else语言翻译成机器代码,可以参考转换成C语言的goto语言格式。类似如下:
if(a+b>0)
c= 1;
else
   c = 2;
goto版本
if(a+b>0)
goto true;
c=2;
true:
c= 1;
3.用条件控制来实现条件分支
如上述例子一样,条件控制方法如C语言中的if/else语句实现条件分支,通过计算a+b的值,然后间接访问上述提及的条件码,此处应访问SF是否为0,经判断,使用跳转指令,实现条件控制。
条件分支的两种方式的对比——条件控制与条件数据 - 中山爷爷 - 凝聚 的博客
 
4.用条件传送来实现条件分支
实现条件操作的传统方法是通过使用控制的条件转移。当条件满足时,程序沿着一条 执行路径执行,而当条件不满足时,就走另一条路径。这种机制简单而通用,但是在现代 处理器上,它可能会非常低效。
一种替代的策略是使用数据的条件转移。这种方法计算一个条件操作的两种结果,然 后再根据条件是否满足从中选取一个。只有在一些受限制的情况中,这种策略才可行,但 是如果可行,就可以用一条简单的条件传送指令来实现它,条件传送指令更符合现代处理 器的性能特性。
条件分支的两种方式的对比——条件控制与条件数据 - 中山爷爷 - 凝聚 的博客

 5.产生的原因
处理 器通过使用流水线(pipelining)来获得高性能,在流水线中,一条指令的处理要经过一系列的阶段,每个阶段执行所需操作的一小部分(例如,从内存取指令、确定指令类型、从内存读数据、执行算术运算、向内存写数据,以及更新程序计数器)。这种方法通过重叠连续指令的步骤来获得高性能,例如,在取一条指令的同时,执行它前面一条指令的算术运算。要做到这一点,要求能够事先确定要执行的指令序列,这样才能保持流水线中充满了待执行的指令。当机器遇到条件跳转(也称为“分支″)时,只有当分支条件求值完成之后,才能决定分支往哪边走。处理器采用非常精密的分支预测逻辑来猜测每条跳转指令是否会执行。只要它的猜测还比较可靠(现代微处理器设计试图达到90%以上的成功率),指令流水线中就会充满着指令。另一方面,错误预测一个跳转, 要求处理器丢掉它为该跳转指令后所有指令已做的工作,然后再开始用从正确位置处起始的指令去填充流水线。正如我们会看到的,这样一个错误预测会招致很严重的惩罚,浪费大约15-30个时钟周期,导致程序性能严重下降。
6.条件传送的有限性
前面提及条件数据的方法更适合现代处理器,但是它是具有有限性,具体的例子如下:条件表达式的一个例子。v = (A-B)? b : c;
改写成goto格式如下:
if(A-B)
goto true;
v = c;
true:
v = b;
改写成条件数据传送:
v1 = b;
v2 = c;
n = A-B;
if(n) v= b;
v = c;
不是所有的条件表达式都可以用条件传送来编译,但是从上述代码可以看出A-B与v=c是肯定要执行的!如果这两个表达式中的任意一个可能产生错误条件或者副作用,就会导致非法的行为。
上面的代码是十分合理的,但是如果是以下形式的条件表达式语句:long sample(long *xp){ return (xp ? *xp : 0;)};

猜你喜欢

转载自blog.csdn.net/amesteur/article/details/80279928
今日推荐