Thread: Why this loop is not optimised out?

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    4

    Why this loop is not optimised out?

    Hello.I've a very simple c program which copies all elements from array A to back to array A. For example,

    Code:
    for( i =0 ; i < SIZE; ++i) {
      A[i] = A[i];
    }
    I was expecting this to be optimised out by the compiler and eventually turned into a noop. However, by measuring the runtime of this loop and looking at the assembly code, it seems that the element is indeed loaded from memory into register and then stored back to the same location memory. Can anyone explain to me why the c compiler does not optimise it? Or am I missing something here?

    Many thanks.

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Do you compile with optimisations turned on?
    Devoted my life to programming...

  3. #3
    Registered User
    Join Date
    Oct 2011
    Posts
    4
    I used -O3, is that enough?

  4. #4
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Quote Originally Posted by jgo View Post
    I used -O3, is that enough?
    Yes, quite enough.

    Maybe the array "A" is declared volatile?
    Devoted my life to programming...

  5. #5
    Registered User
    Join Date
    Oct 2011
    Posts
    4
    no, normal declaration: double *A;

  6. #6
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Quote Originally Posted by jgo View Post
    no, normal declaration: double *A;
    Ohh, it's dynamic right? Sorry, I don't know what optimisation rules apply on dynamic arrays.
    Devoted my life to programming...

  7. #7
    Registered User
    Join Date
    Oct 2011
    Posts
    4
    Yes, it's dynamic. No problem, thanks anyway.

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Here's my test with both dynamic and non-dynamic arrays:

    Code:
    #include <stdlib.h>
    
    
    #define SIZE    10
    
    
    int main(void)
    {
        int i;
        double *A, B[SIZE];
    
    
        A = malloc(SIZE * sizeof(*A));
        for (i = 0; i < SIZE; ++i) {
            A[i] = A[i];
        }
        free(A);
    
    
        for (i = 0; i < SIZE; ++i) {
            B[i] = B[i];
        }
    
    
        return 0;
    }
    After running gcc -Wall -O3 -S optimize.c, I get
    Code:
            .file   "optimize.c"
            .text
            .p2align 4,,15
    .globl main
            .type   main, @function
    main:
            pushl   %ebp
            movl    %esp, %ebp
            andl    $-16, %esp
            subl    $16, %esp
            movl    $80, (%esp)
            call    malloc
            movl    %eax, (%esp)
            call    free
            xorl    %eax, %eax
            leave
            ret
            .size   main, .-main
            .ident  "GCC: (GNU) 4.4.5 20101112 (Red Hat 4.4.5-2)"
            .section        .note.GNU-stack,"",@progbits
    No loop in there. How about -O2:
    Code:
            .file   "optimize.c"
            .text
            .p2align 4,,15
    .globl main
            .type   main, @function
    main:
            pushl   %ebp
            movl    %esp, %ebp
            andl    $-16, %esp
            subl    $16, %esp
            movl    $80, (%esp)
            call    malloc
            movl    %eax, %edx
            leal    80(%eax), %ecx
            .p2align 4,,7
            .p2align 3
    .L2:
            addl    $8, %edx
            cmpl    %ecx, %edx
            jne     .L2
            movl    %eax, (%esp)
            call    free
            xorl    %eax, %eax
            leave
            ret
            .size   main, .-main
            .ident  "GCC: (GNU) 4.4.5 20101112 (Red Hat 4.4.5-2)"
            .section        .note.GNU-stack,"",@progbits
    There it is -- at least, in part. GCC optimizes out the A[i] = A[i] even at -O1, but leaves the loop itself in there until you get to -O3. Note that the B loop is completely removed even at -O1. Fair enough for gcc to optimize general pointers or dynamically allocated memory differently than statically defined arrays, though both loops clearly do nothing. What version of GCC are you running? Can you post the complete code and exact command you used to compile?

    From man gcc on my system:
    Not all optimizations are controlled directly by a flag. Only optimizations that have a flag are listed.
    ...
    -O3 Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions, -funswitch-loops, -fpredictive-commoning,
    -fgcse-after-reload, -ftree-vectorize and -fipa-cp-clone options.
    I compiled the code with -O2 and individually tried each of those -O3 options. None of them eliminated the loop entirely. I can only assume there's some other optimization happening at -O3 that lets gcc eliminate loops involving pointers. If I have time, I might look into GCC's optimizations more.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Nested while loop inside for loop
    By Sonny in forum C Programming
    Replies: 71
    Last Post: 07-31-2011, 08:38 PM
  2. Replies: 23
    Last Post: 04-05-2011, 03:40 PM
  3. The Infinit loop that doesn't loop.
    By errigour in forum C Programming
    Replies: 1
    Last Post: 11-09-2010, 11:31 AM
  4. for loop ignoring scanf inside loop
    By xIcyx in forum C Programming
    Replies: 2
    Last Post: 04-17-2007, 01:46 AM
  5. Replies: 3
    Last Post: 03-14-2006, 11:09 AM