gcc标志以禁用算术优化

问题描述 投票:2回答:1

gcc / g ++是否有用于启用或禁用算术优化的标志,例如a+a+...+a是整数时,n*aa替换的地方?特别是在使用-O2-O3时可以禁用此功能吗?

在下面的示例中,即使是-O0,加法运算也会被一个乘法代替:

$ cat add1.cpp
unsigned int multiply_by_22(unsigned int a)
{
    return a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a;
}

$ g++ -S -masm=intel -O0 add1.cpp

$ cat add1.s
...
        imul    eax, edi, 22

即使禁用-O0(请参阅g++ -c -Q -O0 --help=optimizers | grep enabled)中使用的所有标志仍会产生imul操作。

[添加循环时,它需要-O1来简化对单个乘法的重复加法:

$ cat add2.cpp
unsigned int multiply(unsigned int a, unsigned int b)
{
    unsigned int sum=0;
    for(unsigned int i=0; i<b; i++)
        sum += a;
    return sum;
}

$ g++ -S -masm=intel -O1 add2.cpp

$ cat add2.s
...
        mov     eax, 0
.L3:
        add     eax, 1
        cmp     esi, eax
        jne     .L3
        imul    eax, edi
        ret

-O1已将sum += a;移动到了循环之外,并用一个乘法代替了它。使用-O2,它也将消除死循环。

[我只是想让一些基本的整数运算计时而没有兴趣,并且注意到编译器优化了我的循环,并且我找不到任何标志来禁用此功能。

c++ c gcc compiler-optimization
1个回答
0
投票

我不知道这样的编译器标志。

也许您可以尝试使用volatile作为替代:

unsigned int multiply_by_22(volatile unsigned int a)
{
    return a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a;
}

使用-O0,您将得到:

push    rbp
mov     rbp, rsp
mov     DWORD PTR [rbp-4], edi
mov     edx, DWORD PTR [rbp-4]
mov     eax, DWORD PTR [rbp-4]
add     edx, eax
mov     eax, DWORD PTR [rbp-4]
add     edx, eax
mov     eax, DWORD PTR [rbp-4]
add     edx, eax
mov     eax, DWORD PTR [rbp-4]
add     edx, eax
mov     eax, DWORD PTR [rbp-4]
add     edx, eax
mov     eax, DWORD PTR [rbp-4]
add     edx, eax
mov     eax, DWORD PTR [rbp-4]
add     edx, eax
mov     eax, DWORD PTR [rbp-4]
add     edx, eax
mov     eax, DWORD PTR [rbp-4]
add     edx, eax
mov     eax, DWORD PTR [rbp-4]
add     edx, eax

etc...

似乎也适用于-O2:https://godbolt.org/z/Bk2b6Z

© www.soinside.com 2019 - 2024. All rights reserved.