gcc/g++有启用或禁用算术优化的标志吗?例如,当a
是整数时,a+a+...+a
被替换为n*a
。特别地,在使用-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
也会删除死循环。
我只是出于兴趣在尝试计时一些基本整数操作时发现编译器优化了我的循环,而我无法找到任何禁用此功能的标志。
-O0
,而我们知道这对你来说是不够的。 - Roberto Caboniadd
、imul
、idiv
等操作,我知道有一些很好的在线手册,比如 https://www.agner.org/optimize/instruction_tables.pdf,但在本地复制总是很不错的 :) - user1059432