相关疑难解决方法(0)

为什么GCC不优化a*a*a*a*a*a到(a*a*a)*(a*a*a)?

我正在对科学应用进行一些数值优化.我注意到的一件事是GCC会pow(a,2)通过编译来优化调用a*a,但调用pow(a,6)没有优化,实际上会调用库函数pow,这会大大降低性能.(相比之下,英特尔C++编译器,可执行文件icc,将消除库调用pow(a,6).)

我很好奇的是,当我更换pow(a,6)a*a*a*a*a*a使用GCC 4.5.1和选项" -O3 -lm -funroll-loops -msse4",它采用5分mulsd的说明:

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
Run Code Online (Sandbox Code Playgroud)

如果我写(a*a*a)*(a*a*a),它会产生

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm13, %xmm13
Run Code Online (Sandbox Code Playgroud)

这将乘法指令的数量减少到3. icc具有类似的行为.

为什么编译器不能识别这种优化技巧?

floating-point assembly gcc compiler-optimization fast-math

2083
推荐指数
12
解决办法
20万
查看次数

使用const非整数指数优化pow()?

我的代码中有热点,我pow()占用了大约10-20%的执行时间.

我的输入pow(x,y)是非常具体的,所以我想知道是否有办法滚动两个pow()近似值(每个指数一个)具有更高的性能:

  • 我有两个常数指数:2.4和1/2.4.
  • 当指数为2.4时,x将在范围(0.090473935,1.0)内.
  • 当指数为1/2.4时,x将在范围(0.0031308,1.0)内.
  • 我正在使用SSE/AVX float向量.如果可以利用平台细节,请立即使用!

尽管我对全精度(for float)算法感兴趣,但最大错误率约为0.01%是理想的.

我已经在使用快速pow() 近似,但它没有考虑这些约束.有可能做得更好吗?

c c++ math optimization exponent

60
推荐指数
5
解决办法
1万
查看次数