VS preprocessor definitions Local variables, speed difference

I just compiled the following C code to check the gcc optimizer (using the -O3 flag), expecting both functions to ultimately generate the same set of build instructions:

int test1(int a, int b)
{
#define x (a*a*a+b)
#define y (a*b*a+3*b)
        return x*x+x*y+y;
#undef x
#undef y
}

int test2(int a, int b)
{
        int x = a*a*a+b;
        int y = a*b*a+3*b;
        return x*x+x*y+y;
}

But I was surprised to find that they created a slightly different assembly and that the execution time for test1 (code using a preprocessor instead of local variables) was slightly faster.

, , , , , ; , . , , , ... ?

, ? , , , , -, , -.

, , "gcc test.c-O3-S". gcc - 4.8.2; , gcc, 4.7 4.8 -

test1
        movl    %edi, %eax
        movl    %edi, %edx
        leal    (%rsi,%rsi,2), %ecx
        imull   %edi, %eax
        imull   %esi, %edx
        imull   %edi, %eax
        imull   %edi, %edx
        addl    %esi, %eax
        addl    %ecx, %edx
        leal    (%rax,%rdx), %ecx
        imull   %ecx, %eax
        addl    %edx, %eax
        ret

test2
        movl    %edi, %eax
        leal    (%rsi,%rsi,2), %edx
        imull   %edi, %eax
        imull   %edi, %eax
        leal    (%rax,%rsi), %ecx
        movl    %edi, %eax
        imull   %esi, %eax
        imull   %edi, %eax
        addl    %eax, %edx
        leal    (%rcx,%rdx), %eax
        imull   %ecx, %eax
        addl    %edx, %eax
        ret
+4
2

godbolt GCC, -O . -O, . , .

gcc 4.4.7 -O. , .

test1(int, int):
    movl    %edi, %eax
    imull   %edi, %eax
    imull   %eax, %edi
    addl    $3, %eax
    imull   %esi, %eax
    addl    %esi, %edi
    leal    (%rax,%rdi), %edx
    imull   %edi, %edx
    leal    (%rdx,%rax), %eax
    ret
test2(int, int):
    movl    %edi, %eax
    imull   %edi, %eax
    imull   %eax, %edi
    addl    $3, %eax
    imull   %esi, %eax
    addl    %esi, %edi
    leal    (%rax,%rdi), %edx
    imull   %edi, %edx
    leal    (%rdx,%rax), %eax
    ret
+4

:

  • -
  • "test1 , test2".

. pre () , .

, gcc -E main.c, , , GNU, main.c. :

int test1(int a, int b)
{
  return (a*a*a+b)*(a*a*a+b)+(a*a*a+b)*(a*b*a+3*b)+(a*b*a+3*b);
}

int test2(int a, int b)
{
  int x = a*a*a+b;
  int y = a*b*a+3*b;
  return x*x+x*y+y;
}

, , . ...

(NB: , . , , gcc -S main.c main.s, , , . 2 "" .)

, . . , , , .

int i=100000000;
while (--i>0) {
    int r;
    r = test1(3, 4);
    }

test1 20% , test2.

(r ).

, ,

int r = 0;
while (--i>0) {
    r += test1(3, i);
    }

, . time1 , time2 , .

, , .

, @Ville Krumlinde: , -O (gcc 4.4.7 ). 9 , , "" , .

, .

+1

Source: https://habr.com/ru/post/1583946/


All Articles