我正在尝试优化nbody算法,此操作很昂贵
real s = jMass / POW(distSqr,3.0/2.0);
所以我尝试转换为:
s = jMass * POW(distSqr, -3.0/2.0);
但是带有-Ofast选项的编译器gcc仍然会进行除法,为什么?
答案 0 :(得分:3)
在这里我必须做几个假设(变量都是double
类型,而POW
是一个扩展为pow
的宏):
#include <math.h>
double f0(double a, double b) {
return a / pow(b, 1.5);
}
double f1(double a, double b) {
return a * pow(b, -1.5);
}
这给了我(在x86上):
f0:
.cfi_startproc
movapd %xmm1, %xmm2
sqrtsd %xmm2, %xmm2
mulsd %xmm1, %xmm2
divsd %xmm2, %xmm0
ret
.cfi_endproc
f1:
.cfi_startproc
movapd %xmm1, %xmm2
sqrtsd %xmm2, %xmm2
mulsd %xmm1, %xmm2
divsd %xmm2, %xmm0
ret
.cfi_endproc
将pow(x, 1.5)
转换为x * √x
是合理的优化,因此相除仍然比调用昂贵的pow()
函数要快得多。换句话说,当使用pow(x, -1.5)
时,编译器已经相当合理地选择将1/(x*√x)
表示为-Ofast
。