[英]conditional vs operator?
在GCC(版本4.8.2)手册中,陈述如下:
-ftree-loop-if-convert-stores
:
尝试转换包含内存写入的条件跳转。 这种转换对于多线程程序来说可能是不安全的,因为它将条件内存写入转换为无条件内存写入。 例如,for (i = 0; i < N; i++) if (cond) A[i] = expr;
变成了
for (i = 0; i < N; i++) A[i] = cond ? expr : A[i];
可能产生数据竞争。
但是,我想知道使用operator?
是否有性能提升operator?
与if
语句相对。
A[i]
设置为expr
。 如果不满足,则跳过语句中的代码。 A[i]
似乎都被写入; 条件只影响它设置的值。 通过使用operator?
,我们也在检查; 但是,在不满足条件的情况下,我们会增加一些开销。 我错过了什么吗?
说的是条件跳转转换为条件移动指令 , cmove
系列指令。 它们可以提高速度,因为它们不会像跳转一样停止处理器管道。
使用跳转指令,您不知道要加载哪些指令,因此使用预测并在管道中加载分支。 如果预测是正确的,一切都很好,下一条指令已经在管道上执行。 但是,在评估跳转之后,如果预测错误,则管道中已有的所有以下指令都是无用的,因此必须释放管道,并加载正确的指令。 现代处理器包含16-30级管道,分支误预测会严重降低性能。 有条件的移动绕过了它,因为它们不在程序流中插入分支。
但cmove总是写吗?
来自Intel x86指令集参考:
CMOVcc指令检查EFLAGS寄存器[..]中的一个或多个状态标志的状态,并在标志处于指定状态(或条件)时执行移动操作。 [..]如果不满足条件,则不执行移动,并继续执行CMOVcc指令之后的指令。
编辑
在进一步调查gcc手册后,我感到困惑,因为据我所知,编译器没有优化将C代码转换为另一个C代码,但使用内部数据结构,如控制流图,所以我真的不知道他们的意思是什么他们的榜样。 我认为它们意味着产生的新流量的C等价物。 如果这个优化是关于生成cmoves
。
编辑2
由于cmove
使用寄存器而不是内存,因此
if (cond)
A[i] = expr
无法生成cmove
。
不过这个
A[i] = cond ? expr : A[i];
能够。
假设我们在bx
有expr
值。
load A[i] into ax
cmp // cond
cmove ax, bx
store ax into &A[i]
因此,为了使用cmove
你必须读取A [i]值并将其写回如果cond为false,这与if语句不同,但与三元运算符相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.