[英]conditional vs operator?
In the GCC (version 4.8.2) manual, the following is stated: 在GCC(版本4.8.2)手册中,陈述如下:
-ftree-loop-if-convert-stores
:-ftree-loop-if-convert-stores
:
Attempt to also if-convert conditional jumps containing memory writes.尝试转换包含内存写入的条件跳转。 This transformation can be unsafe for multi-threaded programs as it transforms conditional memory writes into unconditional memory writes.
这种转换对于多线程程序来说可能是不安全的,因为它将条件内存写入转换为无条件内存写入。 For example,
例如,
for (i = 0; i < N; i++) if (cond) A[i] = expr;
is transformed to
变成了
for (i = 0; i < N; i++) A[i] = cond ? expr : A[i];
potentially producing data races.
可能产生数据竞争。
I wonder, however, if there is a performance gain by using the operator?
但是,我想知道使用
operator?
是否有性能提升operator?
versus the if
statement. 与
if
语句相对。
A[i]
is set to expr
only if the condition is met. A[i]
设置为expr
。 If it is not met, then the code inside the statement is skipped. A[i]
seems to be written regardless of the condition; A[i]
似乎都被写入; the condition only affects the value it is set to. By using operator?
通过使用
operator?
, we are also doing a check; ,我们也在检查; however, we are adding some overhead in the case that the condition is not met.
但是,在不满足条件的情况下,我们会增加一些开销。 Have I missed something?
我错过了什么吗?
What is says is that conditional jumps are converted to conditional move instructions , the 说的是条件跳转转换为条件移动指令
cmove
family of instructions. ,
cmove
系列指令。 They improve speed because they do not stall the processor pipeline like jumps do. 它们可以提高速度,因为它们不会像跳转一样停止处理器管道。
With a jump instructions, you don't know in advanced which instructions to load, so a prediction is used and a branch is loaded in the pipeline. 使用跳转指令,您不知道要加载哪些指令,因此使用预测并在管道中加载分支。 If the prediction was correct, all is well, the next instructions are already executing on the pipeline.
如果预测是正确的,一切都很好,下一条指令已经在管道上执行。 However, after the jump is evaluated, if the prediction was wrong, all the following instructions already in the pipeline are useless, so the pipeline must be freed, and the correct instructions are loaded.
但是,在评估跳转之后,如果预测错误,则管道中已有的所有以下指令都是无用的,因此必须释放管道,并加载正确的指令。 Modern processors contain 16-30 stages of pipe, and a branch mispredictions degrade performance severely.
现代处理器包含16-30级管道,分支误预测会严重降低性能。 Conditional moves bypass this because they do not insert branches in the program flow.
有条件的移动绕过了它,因为它们不在程序流中插入分支。
But does cmove always write?
但cmove总是写吗?
From Intel x86 Instruction Set Reference: 来自Intel x86指令集参考:
The CMOVcc instructions check the state of one or more of the status flags in the EFLAGS register [..] and perform a move operation if the flags are in a specified state (or condition).
CMOVcc指令检查EFLAGS寄存器[..]中的一个或多个状态标志的状态,并在标志处于指定状态(或条件)时执行移动操作。 [..] If the condition is not satisfied, a move is not performed and execution continues with the instruction following the CMOVcc instruction.
[..]如果不满足条件,则不执行移动,并继续执行CMOVcc指令之后的指令。
Edit 编辑
Upon further investigating gcc manual, I got confused, because as far as I know the compiler doesn't optimize transforming C code into another C code, but uses internal data structures like Control Flow Graphs so I really don't know what they mean with their example. 在进一步调查gcc手册后,我感到困惑,因为据我所知,编译器没有优化将C代码转换为另一个C代码,但使用内部数据结构,如控制流图,所以我真的不知道他们的意思是什么他们的榜样。 I suppose they mean the C equivalent of the new flow generated.
我认为它们意味着产生的新流量的C等价物。 I am not sure anymore if this optimization is about generating
cmoves
. 如果这个优化是关于生成
cmoves
。
Edit 2 编辑2
Since cmove
operates with registers and not memory, this 由于
cmove
使用寄存器而不是内存,因此
if (cond)
A[i] = expr
cannot generate cmove
. 无法生成
cmove
。
However this 不过这个
A[i] = cond ? expr : A[i];
can. 能够。
Suppose we have in bx
the expr
value. 假设我们在
bx
有expr
值。
load A[i] into ax
cmp // cond
cmove ax, bx
store ax into &A[i]
So in order to use cmove
you have to read A[i] value and write it back if cond if false, which is not equivalent with the if statement, but with the ternary operator. 因此,为了使用
cmove
你必须读取A [i]值并将其写回如果cond为false,这与if语句不同,但与三元运算符相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.