编译器在什么情况下可以改变程序语句的执行顺序?
如果这不是一个真正的问题,那么请随意关闭;)
If this is not a real question then feel free to close ;)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
如果这不是一个真正的问题,那么请随意关闭;)
If this is not a real question then feel free to close ;)
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(3)
不仅编译器可以重新排序执行(主要是为了优化),大多数现代处理器也可以这样做。 详细了解执行重排序和内存屏障。
Not only the compiler can reorder execution (mostly for optimization), most modern processors do so, too. Read more about execution reordering and memory barriers.
当编译器认为适合优化目的并且此类更改不会改变代码的可观察行为时,它可以更改语句的执行顺序。
一个非常简单的例子 -
一个简单的编译器可以按照所示的顺序生成代码。 首先计算“结果”,仅当原始值大于 10 时才返回它(如果不是,“结果”将被忽略 - 不必要地计算)。
然而,一个理智的编译器会发现,只有当“value”大于 10 时才需要计算“result”,因此可以轻松地将计算“value*2”移到第一个大括号内,并且仅在“value”时才进行计算实际上大于 10(不用说,编译器在优化时并不真正查看 C 代码 - 它在较低级别上工作)。
这只是一个简单的例子。 可以创建更复杂的示例。 经过足够积极的优化,C 函数最终很可能看起来几乎与编译形式的 C 表示形式完全不同。
The compiler can change the execution order of statements when it sees fit for optimization purposes, and when such changes wouldn't alter the observable behavior of the code.
A very simple example -
A naive compiler can generate code for this in exactly the sequence shown. First calculate "result" and return it only if the original value is larger than 10 (if it isn't, "result" would be ignored - calculated needlessly).
A sane compiler, though, would see that the calculation of "result" is only needed when "value" is larger than 10, so may easily move the calculation "value*2" inside the first braces and only do it if "value" is actually larger than 10 (needless to mention, the compiler doesn't really look at the C code when optimizing - it works in lower levels).
This is only a simple example. Much more complicated examples can be created. It is very possible that a C function would end up looking almost nothing like its C representation in compiled form, with aggressive enough optimizations.
许多编译器使用称为“公共子表达式消除”的东西。 例如,如果您有以下代码:
编译器会注意到 y * 15 是不变的(其值不会改变)。 因此它将计算 y * 15,将结果保存在寄存器中并将循环语句更改为“x += r0 * i”。 这是一个人为的示例,但是在处理数组索引或任何其他基址+偏移类型的情况时,您经常会看到这样的表达式。
Many compilers use something called "common subexpression elimination". For example, if you had the following code:
the compiler would notice that y * 15 is invariant (its value doesn't change). So it would compute y * 15, stick the result in a register and change the loop statement to "x += r0 * i". This is kind of a contrived example, but you often see expressions like this when working with array indexes or any other base + offset type of situation.