为什么编译器执行此划分

时间:2019-12-18 12:55:02

标签: c gcc

我正在尝试优化nbody算法,此操作很昂贵

real s = jMass / POW(distSqr,3.0/2.0);

所以我尝试转换为:

s = jMass * POW(distSqr, -3.0/2.0);

但是带有-Ofast选项的编译器gcc仍然会进行除法,为什么?

1 个答案:

答案 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

相关问题