Empty loop is slower than a non-empty one in C

后端 未结 4 1414
Happy的楠姐
Happy的楠姐 2020-12-23 19:00

While trying to know how long a line of C code used to execute, I noticed this weird thing :

int main (char argc, char * argv[]) {
    time_t begin, end;
            


        
4条回答
  •  無奈伤痛
    2020-12-23 19:25

    I am able to reproduce this with GCC 4.8.2-19ubuntu1 with no optimization:

    $ ./a.out 
    4.780179
    3.762356
    

    Here is the empty loop:

    0x00000000004005af <+50>:    addq   $0x1,-0x20(%rbp)
    0x00000000004005b4 <+55>:    cmpq   $0x7fffffff,-0x20(%rbp)
    0x00000000004005bc <+63>:    jb     0x4005af 
    

    And here's the non-empty one:

    0x000000000040061a <+157>:   mov    -0x24(%rbp),%eax
    0x000000000040061d <+160>:   cltd   
    0x000000000040061e <+161>:   shr    $0x1f,%edx
    0x0000000000400621 <+164>:   add    %edx,%eax
    0x0000000000400623 <+166>:   and    $0x1,%eax
    0x0000000000400626 <+169>:   sub    %edx,%eax
    0x0000000000400628 <+171>:   add    %eax,-0x28(%rbp)
    0x000000000040062b <+174>:   addq   $0x1,-0x20(%rbp)
    0x0000000000400630 <+179>:   cmpq   $0x7fffffff,-0x20(%rbp)
    0x0000000000400638 <+187>:   jb     0x40061a 
    

    Let's insert a nop in the empty loop:

    0x00000000004005af <+50>:    nop
    0x00000000004005b0 <+51>:    addq   $0x1,-0x20(%rbp)
    0x00000000004005b5 <+56>:    cmpq   $0x7fffffff,-0x20(%rbp)
    0x00000000004005bd <+64>:    jb     0x4005af 
    

    They now run equally fast:

    $ ./a.out 
    3.846031
    3.705035
    

    I imagine this shows the importance of alignment, but I'm afraid I can't specifically say how :|

提交回复
热议问题