问题描述
假设我有2条if
语句:
if (frequency1_mhz > frequency2_hz * 1000) {// some code}
if (frequency1_mhz / 1000 > frequency2_hz ) {// some code}
我猜想这两个函数的功能完全相同,但是我猜测带有乘法的第一个语句比除法更有效。
C ++编译器会对此进行优化吗?还是在设计代码时应该考虑的一件事
解决方法
是,不是。
- 代码不同:
- 由于四舍五入,结果可能有所不同(例如
frequency1_mhz=1001
和frequency2_hz=1
) - 第一个版本可能比第二个版本早溢出。例如
frequency2_hz
等于1000000000会使int
溢出(并导致UB)
- 仍然可以使用乘法进行除法。
不确定时,只需查看生成的程序集即可。
Here's为两个版本生成的程序集。第二个更长,但仍然没有除法。
version1(int,int):
imul esi,esi,1000
xor eax,eax
cmp esi,edi
setl al
ret
version2(int,int):
movsx rax,edi
imul rax,rax,274877907 ; look ma,no idiv!
sar edi,31
sar rax,38
sub eax,edi
cmp eax,esi
setg al
movzx eax,al
ret
,
不,它们不是等效的状态参数,因为除法不是浮点数或整数乘法的精确逆。
- 整数除法将正整数舍入
int f1=999;
int f2=0;
static_assert(f1>f2*1000);
static_assert(f1/1000==f2);
- 倒数并不精确:
static_assert(10.0!=10*(1.0/10));
,
如果它们是使用-O3
构建的浮动,则GCC会生成相同的程序集(无论好坏)
bool first(float frequency1_mhz,float frequency2_hz) {
return frequency1_mhz > frequency2_hz * 1000;
}
bool second(float frequency1_mhz,float frequency2_hz) {
return frequency1_mhz / 1000 > frequency2_hz;
}
first(float,float):
mulss xmm1,DWORD PTR .LC0[rip]
comiss xmm0,xmm1
seta al
ret
second(float,float):
divss xmm0,xmm1
seta al
ret
.LC0:
.long 1148846080