我正在对一个科学应用程序进行一些数值优化。我注意到的一件事是,GCC将通过编译a*a
来优化调用pow(a,2)
,但调用pow(a,6)
没有优化,实际上会调用库函数pow
,这大大降低了性能。(相比之下,英特尔C++编译器,可执行文件icc
,将消除pow(a,6)
的库调用。)
我好奇的是,当我使用GCC 4.5.1和选项“-O3 -lm -funroll-loops -msse4
”将pow(a,6)
替换为a*a*a*a*a*a
时,它使用了5mulsd
指令:
movapd %xmm14, %xmm13mulsd %xmm14, %xmm13mulsd %xmm14, %xmm13mulsd %xmm14, %xmm13mulsd %xmm14, %xmm13mulsd %xmm14, %xmm13
如果我写(a*a*a)*(a*a*a)
,它会产生
movapd %xmm14, %xmm13mulsd %xmm14, %xmm13mulsd %xmm14, %xmm13mulsd %xmm13, %xmm13
这将乘法指令的数量减少到3。icc
也有类似的行为。
为什么编译器不能识别这种优化技巧?