猿问

为什么循环总是被编译成“做…?而“风格”(尾跳)?

为什么循环总是被编译成“做…?而“风格”(尾跳)?

当试图理解程序集(在编译器优化中)时,我看到了以下行为:

像这样一个非常基本的循环

outside_loop;while (condition) {
     statements;}

常被编译成(伪码)


    ; outside_loop
    jmp loop_condition    ; unconditional
loop_start:
    loop_statements
loop_condition:
    condition_check
    jmp_if_true loop_start
    ; outside_loop

但是,如果没有打开优化,它将编译成通常可以理解的代码:

loop_condition:
    condition_check
    jmp_if_false loop_end
    loop_statements
    jmp loop_condition  ; unconditional
loop_end:

根据我的理解,编译后的代码更像这样:

goto condition;do {
    statements;
    condition:}while (condition_check);

我看不到巨大的性能提升或代码可读性提升,那么为什么经常会出现这种情况呢?是否有此循环样式的名称,例如“跟踪条件检查”?


慕容708150
浏览 555回答 3
3回答

慕姐8265434

或者失败,至少进入和超越循环,而不是完全展开的东西,往往运行到1000多个指令。诚然,这是一种时空权衡-但GCC已经通过不展开环路来有效地在这个频谱上定位,因此它与同时生成巨大的intos和/或outros是非常不一致的。

吃鸡游戏

直到GCC没有在默认情况下展开循环。不过,我似乎确实在某些场景中展开,例如嵌套循环和矢量化。这太糟糕了,因为特别是矢量化,你最终会得到一些东西,比如一个巨大的序幕和一个巨大的尾声,然后是一个小的没有展开的循环体。因此,代码的大小是巨大的,但都是为了只执行一次的部分的利益。
随时随地看视频慕课网APP
我要回答