English 中文(简体)
海合会如何最佳地消除在坡道内的未使用变量?
原标题:How does GCC optimize out an unused variable incremented inside a loop?

我撰写了这一简单的C方案:

int main() {
    int i;
    int count = 0;
    for(i = 0; i < 2000000000; i++){
        count = count + 1;
    }
}

我想看到,电梯如何优化这一循环(明确增加1>2000000倍应为“增加<<>2000000 一次”。 因此:

<>strong>gcc test.c, 然后time on a.out 说明:

real 0m7.717s  
user 0m7.710s  
sys 0m0.000s  

$ gcc -O2 test.c and then time ona.out` gives:

real 0m0.003s  
user 0m0.000s  
sys 0m0.000s  

Then I disassembled both with gcc -S. First one seems quite clear:

    .file "test.c"  
    .text  
.globl main
    .type   main, @function  
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    movl    $0, -8(%rbp)
    movl    $0, -4(%rbp)
    jmp .L2
.L3:
    addl    $1, -8(%rbp)
    addl    $1, -4(%rbp)
.L2:
    cmpl    $1999999999, -4(%rbp)
    jle .L3
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
    .section    .note.GNU-stack,"",@progbits

L3补充说,L2将<代码>-4(%rbp)与199999999和如果<代码>i <2000000,则与L3比较。

www.un.org/Depts/DGACM/index_spanish.htm 现在优化的是:。

    .file "test.c"  
    .text
    .p2align 4,,15
.globl main
    .type main, @function
main:
.LFB0:
    .cfi_startproc
    rep
    ret
    .cfi_endproc
.LFE0:
    .size main, .-main
    .ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
    .section .note.GNU-stack,"",@progbits

I can t understand at all what s going on there! I ve got little knowledge of assembly, but I expected something like

addl $2000000000, -8(%rbp)

我甚至尝试了gcc -c -g - Wa,-a,-ad -O2 test.c,以便看到《刑法》与《法典》的大会一起被转换成,但结果再清楚表明前一部法典。

www.un.org/Depts/DGACM/index_spanish.htm 请允许我简要解释:。

  1. The gcc -S -O2 output.
  2. If the loop is optimized as I expected (one sum instead of many sums)?
最佳回答

汇编者甚至具有以下特点:

In fact, it realizes that you aren t using the result of the loop. So it took out the entire loop completely!

http://en.wikipedia.org/wiki/Dead_code_elimination”rel=“noreferer” 死亡法典消除

更好的测试是印刷结果:

#include <stdio.h>
int main(void) {
    int i; int count = 0;
    for(i = 0; i < 2000000000; i++){
        count = count + 1;
    }

    //  Print result to prevent Dead Code Elimination
    printf("%d
", count);
}

http://www.un.org。 I ve 添加了所要求的<代码>#include <stdio.h>; 缩略语组的组装与没有#include的版本相对应,但也应如此。


我当时在我前面没有海合会,因为我把我boot到Windows。 但是,此处将本版本与MSVC的分开:

EDIT:我有错的组装产出。 页: 1

; 57   : int main(){

$LN8:
    sub rsp, 40                 ; 00000028H

; 58   : 
; 59   : 
; 60   :     int i; int count = 0;
; 61   :     for(i = 0; i < 2000000000; i++){
; 62   :         count = count + 1;
; 63   :     }
; 64   : 
; 65   :     //  Print result to prevent Dead Code Elimination
; 66   :     printf("%d
",count);

    lea rcx, OFFSET FLAT:??_C@_03PMGGPEJJ@?$CFd?6?$AA@
    mov edx, 2000000000             ; 77359400H
    call    QWORD PTR __imp_printf

; 67   : 
; 68   : 
; 69   : 
; 70   :
; 71   :     return 0;

    xor eax, eax

; 72   : }

    add rsp, 40                 ; 00000028H
    ret 0

因此,视频演播室这样做是最佳的。 d 我假定海合会可能也这样做。

是的,海合会进行类似的优化。 此处用<条码>gcc-S-O2 测试.c(gcc 4.5.2, 乌班图11.10,x86)列出同一方案的组:

        .file   "test.c"
        .section        .rodata.str1.1,"aMS",@progbits,1
.LC0:
        .string "%d
"
        .text
        .p2align 4,,15
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        andl    $-16, %esp
        subl    $16, %esp
        movl    $2000000000, 8(%esp)
        movl    $.LC0, 4(%esp)
        movl    $1, (%esp)
        call    __printf_chk
        leave
        ret
        .size   main, .-main
        .ident  "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
        .section        .note.GNU-stack,"",@progbits
问题回答

汇编者可使用一些工具,提高代码的效率或提高“效率”:

  1. 如果计算结果从未使用过,可省略进行计算(如果计算依据<代码>volatus)。 这些价值观仍然必须阅读,但阅读结果可能被忽视。 如果计算结果是用的吨数,则执行这些方法的代码也可以删除。 如果这种疏漏使有条件的分行的两条道路的代码相同,则该条件可被视为未使用和遗漏。 这样做不会影响任何方案的行为(除执行时间外),这些方案不提供有约束的记忆,或援引附件L所称的“非明确决定因素”。

  2. If the compiler determines that the machine code that computes a value can only produce results in a certain range, it may omit any conditional tests whose outcome could be predicted on that basis. As above, this will not affect behaviors other than execution time unless code invokes "Critical Undefined Behaviors".

  3. 如果汇编者确定某些投入会以书面形式援引任何形式未经界定的决定因素,则《标准》将允许汇编者排除任何只有在收到这些投入时才具有相关性的守则,即使考虑到这些投入,执行平台的自然行为会变得合情合理,汇编者改写法会使其变得危险。

好编者是第1和第2号。 然而,出于某种原因,第3号已成为可变的。





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...